Wie führe ich eine IF...THEN
in einer SQL SELECT
Anweisung durch?
Zum Beispiel:
SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product
WHERE
und CHECK
aber nicht SELECT
.
Wie führe ich eine IF...THEN
in einer SQL SELECT
Anweisung durch?
Zum Beispiel:
SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product
WHERE
und CHECK
aber nicht SELECT
.
Antworten:
Die CASE
Anweisung kommt IF in SQL am nächsten und wird von allen Versionen von SQL Server unterstützt.
SELECT CAST(
CASE
WHEN Obsolete = 'N' or InStock = 'Y'
THEN 1
ELSE 0
END AS bit) as Saleable, *
FROM Product
Sie müssen dies nur tun, CAST
wenn Sie das Ergebnis als Booleschen Wert wünschen. Wenn Sie mit einem zufrieden sind int
, funktioniert dies:
SELECT CASE
WHEN Obsolete = 'N' or InStock = 'Y'
THEN 1
ELSE 0
END as Saleable, *
FROM Product
CASE
Anweisungen können in andere CASE
Anweisungen eingebettet und sogar in Aggregaten enthalten sein.
SQL Server Denali (SQL Server 2012) fügt die IIF- Anweisung hinzu, die auch im Zugriff verfügbar ist (von Martin Smith hervorgehoben ):
SELECT IIF(Obsolete = 'N' or InStock = 'Y', 1, 0) as Saleable, * FROM Product
Die case-Anweisung ist in dieser Situation Ihr Freund und hat eine von zwei Formen:
Der einfache Fall:
SELECT CASE <variable> WHEN <value> THEN <returnvalue>
WHEN <othervalue> THEN <returnthis>
ELSE <returndefaultcase>
END AS <newcolumnname>
FROM <table>
Der erweiterte Fall:
SELECT CASE WHEN <test> THEN <returnvalue>
WHEN <othertest> THEN <returnthis>
ELSE <returndefaultcase>
END AS <newcolumnname>
FROM <table>
Sie können sogar case-Anweisungen in eine order by-Klausel einfügen, um eine wirklich ausgefallene Bestellung zu erhalten.
AS Col_Name
nach dem hinzufügen können, um END
die resultierende Spalte zu benennen
Ab SQL Server 2012 können Sie die IIF
Funktion hierfür verwenden.
SELECT IIF(Obsolete = 'N' OR InStock = 'Y', 1, 0) AS Salable, *
FROM Product
Dies ist praktisch nur eine Kurzschrift (wenn auch keine Standard-SQL-Schreibweise) CASE
.
Ich bevorzuge die Prägnanz im Vergleich zur erweiterten CASE
Version.
Beide IIF()
und CASE
lösen sich als Ausdrücke innerhalb einer SQL-Anweisung auf und können nur an genau definierten Stellen verwendet werden.
Der CASE-Ausdruck kann nicht zur Steuerung des Ausführungsflusses von Transact-SQL-Anweisungen, Anweisungsblöcken, benutzerdefinierten Funktionen und gespeicherten Prozeduren verwendet werden.
Wenn Ihre Anforderungen durch diese Einschränkungen nicht erfüllt werden können (z. B. die Notwendigkeit, abhängig von einer bestimmten Bedingung unterschiedlich geformte Ergebnismengen zurückzugeben), verfügt SQL Server auch über ein prozedurales IF
Schlüsselwort.
IF @IncludeExtendedInformation = 1
BEGIN
SELECT A,B,C,X,Y,Z
FROM T
END
ELSE
BEGIN
SELECT A,B,C
FROM T
END
Sie finden einige schöne Beispiele in The Power of SQL CASE-Anweisungen , und ich denke, die Anweisung, die Sie verwenden können, wird ungefähr so aussehen (von 4guysfromrolla ):
SELECT
FirstName, LastName,
Salary, DOB,
CASE Gender
WHEN 'M' THEN 'Male'
WHEN 'F' THEN 'Female'
END
FROM Employees
SELECT
(CASE
WHEN (Obsolete = 'N' OR InStock = 'Y') THEN 'YES'
ELSE 'NO'
END) as Salable
, *
FROM Product
Microsoft SQL Server (T-SQL)
In einem select
, verwenden:
select case when Obsolete = 'N' or InStock = 'Y' then 'YES' else 'NO' end
where
Verwenden Sie in einer Klausel:
where 1 = case when Obsolete = 'N' or InStock = 'Y' then 1 else 0 end
where Obsolete = 'N' or InStock = 'Y'
das wo praktisch
Aus diesem Link können wir IF THEN ELSE
in T-SQL verstehen :
IF EXISTS(SELECT *
FROM Northwind.dbo.Customers
WHERE CustomerId = 'ALFKI')
PRINT 'Need to update Customer Record ALFKI'
ELSE
PRINT 'Need to add Customer Record ALFKI'
IF EXISTS(SELECT *
FROM Northwind.dbo.Customers
WHERE CustomerId = 'LARSE')
PRINT 'Need to update Customer Record LARSE'
ELSE
PRINT 'Need to add Customer Record LARSE'
Ist das nicht gut genug für T-SQL?
SELECT
CASE
WHEN OBSOLETE = 'N' or InStock = 'Y' THEN 'TRUE'
ELSE 'FALSE'
END AS Salable,
*
FROM PRODUCT
Einfache if-else-Anweisung in SQL Server:
DECLARE @val INT;
SET @val = 15;
IF @val < 25
PRINT 'Hi Ravi Anand';
ELSE
PRINT 'By Ravi Anand.';
GO
Verschachtelte If ... else-Anweisung in SQL Server -
DECLARE @val INT;
SET @val = 15;
IF @val < 25
PRINT 'Hi Ravi Anand.';
ELSE
BEGIN
IF @val < 50
PRINT 'what''s up?';
ELSE
PRINT 'Bye Ravi Anand.';
END;
GO
SELECT
wie OP gefragt hat?
Eine neue Funktion, IIF (die wir einfach verwenden können), wurde in SQL Server 2012 hinzugefügt:
SELECT IIF ( (Obsolete = 'N' OR InStock = 'Y'), 1, 0) AS Saleable, * FROM Product
Verwenden Sie reine Bitlogik:
DECLARE @Product TABLE (
id INT PRIMARY KEY IDENTITY NOT NULL
,Obsolote CHAR(1)
,Instock CHAR(1)
)
INSERT INTO @Product ([Obsolote], [Instock])
VALUES ('N', 'N'), ('N', 'Y'), ('Y', 'Y'), ('Y', 'N')
;
WITH cte
AS
(
SELECT
'CheckIfInstock' = CAST(ISNULL(NULLIF(ISNULL(NULLIF(p.[Instock], 'Y'), 1), 'N'), 0) AS BIT)
,'CheckIfObsolote' = CAST(ISNULL(NULLIF(ISNULL(NULLIF(p.[Obsolote], 'N'), 0), 'Y'), 1) AS BIT)
,*
FROM
@Product AS p
)
SELECT
'Salable' = c.[CheckIfInstock] & ~c.[CheckIfObsolote]
,*
FROM
[cte] c
Siehe Arbeitsdemo: Wenn dann ohne case
in SQL Server .
Zu Beginn müssen Sie den Wert true
und false
für ausgewählte Bedingungen berechnen . Hier kommen zwei NULLIF :
for true: ISNULL(NULLIF(p.[Instock], 'Y'), 1)
for false: ISNULL(NULLIF(p.[Instock], 'N'), 0)
kombiniert ergibt 1 oder 0. Verwenden Sie als nächstes bitweise Operatoren .
Es ist die WYSIWYG- Methode.
SELECT 1 AS Saleable, *
FROM @Product
WHERE ( Obsolete = 'N' OR InStock = 'Y' )
UNION
SELECT 0 AS Saleable, *
FROM @Product
WHERE NOT ( Obsolete = 'N' OR InStock = 'Y' )
SELECT CASE WHEN profile.nrefillno = 0 THEN 'N' ELSE 'R'END as newref
From profile
case statement some what similar to if in SQL server
SELECT CASE
WHEN Obsolete = 'N' or InStock = 'Y'
THEN 1
ELSE 0
END as Saleable, *
FROM Product
Dies ist keine Antwort, sondern nur ein Beispiel für eine CASE-Anweisung, die bei meiner Arbeit verwendet wird. Es hat eine verschachtelte CASE-Anweisung. Jetzt wissen Sie, warum meine Augen gekreuzt sind.
CASE orweb2.dbo.Inventory.RegulatingAgencyName
WHEN 'Region 1'
THEN orweb2.dbo.CountyStateAgContactInfo.ContactState
WHEN 'Region 2'
THEN orweb2.dbo.CountyStateAgContactInfo.ContactState
WHEN 'Region 3'
THEN orweb2.dbo.CountyStateAgContactInfo.ContactState
WHEN 'DEPT OF AGRICULTURE'
THEN orweb2.dbo.CountyStateAgContactInfo.ContactAg
ELSE (
CASE orweb2.dbo.CountyStateAgContactInfo.IsContract
WHEN 1
THEN orweb2.dbo.CountyStateAgContactInfo.ContactCounty
ELSE orweb2.dbo.CountyStateAgContactInfo.ContactState
END
)
END AS [County Contact Name]
CASE
wandere nur umher, warum ich als Antwort hochgestuft und markiert werde, anstatt als die, IF
die die Antwort hätte sein sollen, wie diese, dies ist immer noch eine CASE
Aussage, keine IF
.
Wenn Sie Ergebnisse zum ersten Mal in eine Tabelle einfügen, anstatt Ergebnisse von einer Tabelle in eine andere zu übertragen, funktioniert dies in Oracle 11.2g:
INSERT INTO customers (last_name, first_name, city)
SELECT 'Doe', 'John', 'Chicago' FROM dual
WHERE NOT EXISTS
(SELECT '1' from customers
where last_name = 'Doe'
and first_name = 'John'
and city = 'Chicago');
Als alternative Lösung zur CASE
Aussage kann ein tabellengesteuerter Ansatz verwendet werden:
DECLARE @Product TABLE (ID INT, Obsolete VARCHAR(10), InStock VARCHAR(10))
INSERT INTO @Product VALUES
(1,'N','Y'),
(2,'A','B'),
(3,'N','B'),
(4,'A','Y')
SELECT P.* , ISNULL(Stmt.Saleable,0) Saleable
FROM
@Product P
LEFT JOIN
( VALUES
( 'N', 'Y', 1 )
) Stmt (Obsolete, InStock, Saleable)
ON P.InStock = Stmt.InStock OR P.Obsolete = Stmt.Obsolete
Ergebnis:
ID Obsolete InStock Saleable
----------- ---------- ---------- -----------
1 N Y 1
2 A B 0
3 N B 1
4 A Y 1
SELECT CASE WHEN Obsolete = 'N' or InStock = 'Y' THEN 1 ELSE 0
END AS Saleable, *
FROM Product
Für diejenigen, die SQL Server 2012 verwenden, ist IIF eine Funktion, die hinzugefügt wurde und als Alternative zu Case-Anweisungen fungiert.
SELECT IIF(Obsolete = 'N' OR InStock = 'Y', 1, 0) AS Salable, *
FROM Product
SELECT IIF(Obsolete = 'N' OR InStock = 'Y',1,0) AS Saleable, * FROM Product
Sie haben zwei Möglichkeiten, um dies tatsächlich zu implementieren:
Verwenden von IIF, das von SQL Server 2012 eingeführt wurde:
SELECT IIF ( (Obsolete = 'N' OR InStock = 'Y'), 1, 0) AS Saleable, * FROM Product
Verwenden von Select Case
:
SELECT CASE
WHEN Obsolete = 'N' or InStock = 'Y'
THEN 1
ELSE 0
END as Saleable, *
FROM Product
Frage:
SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product
ANSI:
Select
case when p.Obsolete = 'N'
or p.InStock = 'Y' then 1 else 0 end as Saleable,
p.*
FROM
Product p;
Die Verwendung von Aliasen - p
in diesem Fall - hilft, Probleme zu vermeiden.
Die Verwendung von SQL CASE entspricht den normalen If / Else-Anweisungen. In der folgenden Abfrage: Wenn der veraltete Wert = 'N' oder der InStock-Wert = 'Y' ist, ist die Ausgabe 1. Andernfalls ist die Ausgabe 0. Dann setzen wir diesen 0- oder 1-Wert unter die verkaufsfähige Spalte.
SELECT
CASE
WHEN obsolete = 'N' OR InStock = 'Y'
THEN 1
ELSE 0
END AS Salable
, *
FROM PRODUCT
If..Then...Else..
SQL
SELECT
CAST(
CASE WHEN Obsolete = 'N'
or InStock = 'Y' THEN ELSE 0 END AS bit
) as Saleable, *
FROM
Product
Es wird so etwas sein:
SELECT OrderID, Quantity,
CASE
WHEN Quantity > 30 THEN "The quantity is greater than 30"
WHEN Quantity = 30 THEN "The quantity is 30"
ELSE "The quantity is under 30"
END AS QuantityText
FROM OrderDetails;
SELECT OrderID, Quantity, CASE WHEN Quantity > 30 THEN "The quantity is greater than 30" WHEN Quantity = 30 THEN "The quantity is 30" ELSE "The quantity is under 30" END AS QuantityText FROM OrderDetails WHERE QuantityText = 'The quantity is 30';
Der Vollständigkeit halber möchte ich hinzufügen, dass SQL dreiwertige Logik verwendet. Der Ausdruck:
obsolete = 'N' OR instock = 'Y'
Könnte drei unterschiedliche Ergebnisse liefern:
| obsolete | instock | saleable |
|----------|---------|----------|
| Y | Y | true |
| Y | N | false |
| Y | null | null |
| N | Y | true |
| N | N | true |
| N | null | true |
| null | Y | true |
| null | N | null |
| null | null | null |
Wenn zum Beispiel ein Produkt veraltet ist, Sie aber nicht wissen, ob das Produkt instock ist, wissen Sie nicht, ob das Produkt verkaufsfähig ist. Sie können diese dreiwertige Logik wie folgt schreiben:
SELECT CASE
WHEN obsolete = 'N' OR instock = 'Y' THEN 'true'
WHEN NOT (obsolete = 'N' OR instock = 'Y') THEN 'false'
ELSE NULL
END AS saleable
Sobald Sie herausgefunden haben, wie es funktioniert, können Sie drei Ergebnisse in zwei Ergebnisse konvertieren, indem Sie das Verhalten von null festlegen. Zum Beispiel würde dies null als nicht verkaufsfähig behandeln:
SELECT CASE
WHEN obsolete = 'N' OR instock = 'Y' THEN 'true'
ELSE 'false' -- either false or null
END AS saleable
Ich mag die Verwendung der CASE-Anweisungen, aber die Frage nach einer IF-Anweisung in SQL Select. Was ich in der Vergangenheit verwendet habe, war:
SELECT
if(GENDER = "M","Male","Female") as Gender
FROM ...
Es ist wie bei den IF-Anweisungen von Excel oder Sheets, bei denen eine Bedingung gefolgt von der wahren Bedingung und dann der falschen Bedingung vorliegt:
if(condition, true, false)
Außerdem können Sie die if-Anweisungen verschachteln (aber dann sollte use ein CASE verwenden :-)
(Hinweis: Dies funktioniert in MySQLWorkbench, aber möglicherweise nicht auf anderen Plattformen.)
Sie können Case Statement verwenden:
Select
Case WHEN (Obsolete = 'N' or InStock = 'Y') THEN 1 ELSE 0 END Saleable,
Product.*
from Product