Gibt einen Wert zurück, wenn in Microsoft tSQL keine Zeilen gefunden werden

95

Unter Verwendung einer Microsoft- Version von SQL ist hier meine einfache Abfrage. Wenn ich einen Datensatz abfrage, der nicht vorhanden ist, wird nichts zurückgegeben. Ich würde es vorziehen, wenn in diesem Szenario false (0) zurückgegeben wird. Suchen Sie nach der einfachsten Methode, um keine Datensätze zu berücksichtigen.

SELECT  CASE
            WHEN S.Id IS NOT NULL AND S.Status = 1 AND (S.WebUserId = @WebUserId OR S.AllowUploads = 1) THEN 1
            ELSE 0
        END AS [Value]

        FROM Sites S

        WHERE S.Id = @SiteId
Matt
quelle

Antworten:

64
SELECT CASE WHEN COUNT(1) > 0 THEN 1 ELSE 0 END AS [Value]

FROM Sites S

WHERE S.Id = @SiteId and S.Status = 1 AND 
      (S.WebUserId = @WebUserId OR S.AllowUploads = 1)
Adam Robinson
quelle
Die folgende Abfrage gibt einen Einzelwert im else-Zustand zurück, sollte jedoch idealerweise mehrere Werte zurückgeben. Wählen Sie den Fall aus, wenn count (QTIB_REQ _) <1, dann 0, andernfalls QTIB_REQ_ von qb_requisitions_all endet, wobei QTIB_REQ_ IN ($ Req_disabled_WA) und CLIENT___BENCH___NON_BILLABLE NOT IN ('Non Billable', 'Non-Billable', 'NonBillable', 'Non-Billable', 'NonBillable', 'Non-Billable', 'NonBillable' SC Cleared Strategic Hires ',' Bench / US-Projekt ') und DATEDIFF (CURDATE (), TARGET_FILL_DATE) <60 und DATEDIFF (CURDATE (), TARGET_FILL_DATE)> 0
Praneet Bahadur
121

Dies ähnelt dem von Adam Robinson, verwendet jedoch ISNULL anstelle von COUNT.

SELECT ISNULL(
(SELECT 1 FROM Sites S
WHERE S.Id = @SiteId and S.Status = 1 AND 
      (S.WebUserId = @WebUserId OR S.AllowUploads = 1)), 0)

Wenn die innere Abfrage eine übereinstimmende Zeile hat, wird 1 zurückgegeben. Die äußere Abfrage (mit ISNULL) gibt dann den Wert 1 zurück. Wenn die innere Abfrage keine übereinstimmende Zeile enthält, gibt sie nichts zurück. Die äußere Abfrage behandelt dies wie NULL, sodass ISNULL am Ende 0 zurückgibt.

Moe Sisko
quelle
2
Vielen Dank für das Hinzufügen dieses! Es ist genau das, was ich brauche, da ich einfach ISNULL AUSWÄHLEN könnte ((SELECT Id ... anstelle von 1, um die Daten zu erhalten, nach denen ich gesucht habe!
Jesse Smith
3
Sehr spät, ich weiß, aber Sie können ISNULL durch COALESCE ersetzen, um das gleiche Ergebnis zu erzielen.
BlueChippy
2
Ich habe mir angewöhnt, COALESCE anstelle von ISNULL zu verwenden, da ISNULL aus dem Speicher (Gewohnheiten sterben schwer) in SQL Lite oder wie auch immer es heißt, das auf älteren Windows Mobile-Geräten ausgeführt wird, nicht verfügbar ist. COALESCE funktioniert sowohl mit Lite-, Express- als auch mit vollständigem SQL.
Anzeigen
1
Es funktioniert besser, wenn Sie einen variablen Wert anstelle von 0 oder 1 erhalten möchten. Adams Abfrage erfordert eine Gruppierung oder ähnliches.
Drac
@MoeSisko Ich mag es, wie es die 0 zurückgibt, wenn es null ist, aber anstatt eine 1 zurückzugeben, wie kann ich es dazu bringen, den Wert aus der Tabelle zurückzugeben?
Michael
21

Dies kann ein totes Pferd sein. Eine andere Möglichkeit, 1 Zeile zurückzugeben, wenn keine Zeilen vorhanden sind, besteht darin, eine weitere Abfrage an UNION zu senden und Ergebnisse anzuzeigen, wenn diese nicht in der Tabelle vorhanden sind.

SELECT S.Status, COUNT(s.id) AS StatusCount
FROM Sites S
WHERE S.Id = @SiteId
GROUP BY s.Status
UNION ALL --UNION BACK ON TABLE WITH NOT EXISTS
SELECT 'N/A' AS Status, 0 AS StatusCount
WHERE NOT EXISTS (SELECT 1
   FROM Sites S
   WHERE S.Id = @SiteId
) 
ein Agent
quelle
2
Ich habe eine ähnliche Methode verwendet, um Summen aus einer Abfrage zu erhalten. Ich habe einfach eine Union mit einer Abfrage durchgeführt, die 0 ( SELECT 0) zurückgegeben hat, und dann eine SUMUnion. Einfach und leicht zu folgen.
CJBarth
2
Wenn 2 Zeilen zurückgegeben werden, ist dann garantiert, dass die Zeilen in der erwarteten Reihenfolge zurückgegeben werden?
Sarsaparilla
Und es ist schwer auf dem Hinrichtungsplan
Fandango68
12

Etwas wie:

if exists (select top 1 * from Sites S where S.Id IS NOT NULL AND S.Status = 1 AND (S.WebUserId = @WebUserId OR S.AllowUploads = 1))
    select 1
else
    select 0
Ellis
quelle
Ich habe diese Lösung verwendet, da sie für mich sinnvoller ist (ich bin traditionell kein SQL-Benutzer). Ich verwende jedoch SQL Server. Ich habe festgestellt, dass das Hinzufügen des Spaltennamens zu dieser Lösung diese Lösung gut abrundet. dh nachdem du select 1und select 2ich hinzugefügt habenas <colName>
Harvey
8

Ich habe alle Antworten hier gelesen und es hat eine Weile gedauert, um herauszufinden, was los war. Das Folgende basiert auf der Antwort von Moe Sisko und einigen verwandten Forschungen

Wenn Ihre SQL-Abfrage keine Daten zurückgibt, gibt es kein Feld mit einem Nullwert, sodass weder ISNULL noch COALESCE so funktionieren, wie Sie es möchten. Bei Verwendung einer Unterabfrage erhält die Abfrage der obersten Ebene ein Feld mit einem Nullwert, und sowohl ISNULL als auch COALESCE funktionieren so, wie Sie es möchten / erwarten.

Meine Anfrage

select isnull(
 (select ASSIGNMENTM1.NAME
 from dbo.ASSIGNMENTM1
 where ASSIGNMENTM1.NAME = ?)
, 'Nothing Found') as 'ASSIGNMENTM1.NAME'

Meine Anfrage mit Kommentaren

select isnull(
--sub query either returns a value or returns nothing (no value)
 (select ASSIGNMENTM1.NAME
 from dbo.ASSIGNMENTM1
 where ASSIGNMENTM1.NAME = ?)
 --If there is a value it is displayed 
 --If no value, it is perceived as a field with a null value, 
 --so the isnull function can give the desired results
, 'Nothing Found') as 'ASSIGNMENTM1.NAME'
James Jenkins
quelle
5

Sie müssen nur das WHERE durch ein LEFT JOIN ersetzen:

SELECT  CASE
        WHEN S.Id IS NOT NULL AND S.Status = 1 AND ...) THEN 1
        ELSE 0
    END AS [Value]

    FROM (SELECT @SiteId AS Id) R
    LEFT JOIN Sites S ON S.Id = R.Id

Mit dieser Lösung können Sie auch Standardwerte für jede Spalte zurückgeben, zum Beispiel:

SELECT
    CASE WHEN S.Id IS NULL THEN 0 ELSE S.Col1 END AS Col1,
    S.Col2,
    ISNULL(S.Col3, 0) AS Col3
FROM
    (SELECT @Id AS Id) R
    LEFT JOIN Sites S ON S.Id = R.Id AND S.Status = 1 AND ...
Sarsaparille
quelle
4

Kein übereinstimmender Datensatz bedeutet, dass kein Datensatz zurückgegeben wird. Es gibt keinen Platz für den "Wert" von 0, wenn keine Datensätze gefunden werden. Sie könnten eine verrückte UNION-Abfrage erstellen, um das zu tun, was Sie wollen, aber viel, viel, viel besser, um einfach die Anzahl der Datensätze in der Ergebnismenge zu überprüfen.

Larry Lustig
quelle
Derzeit mache ich das so. Überprüfen Sie, ob die Datensatzanzahl leer ist oder nicht. Ich dachte, sie könnten eine Möglichkeit gewesen sein, meinen Scheck zu verkürzen.
Matt
Einige Apps erlauben es Ihnen nicht "einfach" zu überprüfen
Nadia Solovyeva
3

Dies könnte eine Möglichkeit sein.

SELECT TOP 1 [Column Name] FROM (SELECT [Column Name] FROM [table]
    WHERE [conditions]
    UNION ALL
    SELECT 0 )A ORDER BY [Column Name] DESC
Gopal V.
quelle
Ich mag diesen Ansatz. Ich denke, es ist etwas sauberer, wenn die Standarddaten ausgedrückt werden, insbesondere wenn Sie am Ende zahlreiche Spalten mit Daten / Standardwerten haben.
Markieren Sie an der Rampe 51
Lol das ist die beste und sauberste Lösung
Kyle Bridenstine
1

Was ist mit Krawatten?

SELECT TOP 1 WITH TIES tbl1.* FROM 
        (SELECT CASE WHEN S.Id IS NOT NULL AND S.Status = 1 
                      AND (S.WebUserId = @WebUserId OR 
                           S.AllowUploads = 1)
                     THEN 1 
                     ELSE 0 AS [Value]
         FROM Sites S
         WHERE S.Id = @SiteId) as tbl1
ORDER BY tbl1.[Value]
Fandango68
quelle
1
DECLARE @col int; 
select @col = id  FROM site WHERE status = 1; 
select coalesce(@col,0);
Schwarz
quelle
0

@ hai-phans Antwort mit LEFT JOINist der Schlüssel, aber es könnte etwas schwierig sein, ihm zu folgen. Ich hatte eine komplizierte Abfrage, die möglicherweise auch nichts zurückgibt. Ich habe nur seine Antwort auf meine Bedürfnisse vereinfacht. Es ist einfach, Abfragen mit vielen Spalten anzuwenden.

;WITH CTE AS (
  -- SELECT S.Id, ...
  -- FROM Sites S WHERE Id = @SiteId
  -- EXCEPT SOME CONDITION.
  -- Whatever your query is
)
SELECT CTE.* -- If you want something else instead of NULL, use COALESCE.
FROM (SELECT @SiteId AS ID) R
LEFT JOIN CTE ON CTE.Id = R.ID

Update: Diese Antwort auf SqlServerCentral ist die beste. Es nutzt diese Funktion von MAX - "MAX gibt NULL zurück, wenn keine Zeile zur Auswahl steht."

SELECT ISNULL(MAX(value), 0) FROM table WHERE Id = @SiteId
Weihui Guo
quelle
0
You should avoid using expensive methods. You dont need any column for TBL2. 

SELECT COUNT(*) FROM(
         SELECT TOP 1     1 AS CNT  FROM  TBL1 
         WHERE ColumnValue ='FooDoo'  ) AS TBL2

or

IF EXISTS (SELECT TOP 1 1 FROM TABLE1 AS T1 
                          WHERE T1.ColumnValue='VooDoo') 
   SELECT 1 
ELSE 
   SELECT 0
Ayhan Sarıtaş
quelle