2016-08-08 31 views
3

Ich bin ziemlich rostig mit meinem SQL-Spiel. Ich habe einen Code (siehe unten), der eine Datenbankinstanz überprüft (instance001, instance002, usw.) und dann nach den LAST_READ- und LAST_WRITE-Feldern sucht, die null sind, sowie bei der letzten Zurücksetzung. Nichts zu übertrieben.SQL Server: Wo und Wie Statements

Das Problem, das ich habe, ist, wie Sie dies über mehrere Instanzen hinweg ausführen. Du wirst sehen, ich habe einen Abschnitt auskommentiert. Wenn ich die entsprechende OR-Anweisung (or inst_name like 'instance002') hinzufüge, erhält es nicht die Ergebnisse, nach denen ich gesucht habe.

Beispiel: instance001 ergibt 1 Datensätze. instance002 ergibt 60. Wenn ich where inst_name like 'instance001' or inst_name like 'instance002' verwende, erhalte ich 210 Datensätze. Wie würde ich die SQL manipulieren, um 61 zur Verfügung zu stellen?

declare @timeString nvarchar(50) = CONVERT(varchar(24), GETDATE(), 120) 
select DB_NAME, INST_NAME, MIN([LAST_SRVR_RST]) AS MIN_SRVR_RST, LAST_READ, LAST_WRITE, [email protected] 
from CMS_DB_LAST_READ_WRITE  -- Targeted DB with data. 
where inst_name     -- Targeted instance(s) 
    like 'instance001' 
    /* 
    like 'instance002' 
    like 'instance003' 
    like 'instance004' 
    */ 
    and LAST_READ is null  -- Both read and write must be null 
    and LAST_WRITE is null  -- to show no activity. 
    --and [LAST_SRVR_RST] = MIN([LAST_SRVR_RST]) 
group by DB_NAME, INST_NAME, LAST_SRVR_RST, LAST_READ, LAST_WRITE 

Antwort

4

AND takes precedence over OR, müssen Sie Gruppe um die beiden Bedingungen unter Verwendung von Klammern:

... 
WHERE (inst_name = 'instance001' OR inst_name = 'instance002') 
AND LAST_READ IS NULL 
AND LAST_WRITE IS NULL 
GROUP BY ... 

Hinweis: änderte ich die Nutzung LIKE-=, wie Sie nach einer genauen Übereinstimmung suchen, und es doesn Es macht keinen Sinn, LIKE in dieser Situation zu verwenden.

Der Grund für die Gruppierung liegt an der oben genannten Rangfolge. Dieser Auftrag ist:

Level Operators 
1  ~ (Bitwise NOT) 
2  * (Multiply),/(Division), % (Modulo) 
3  + (Positive), - (Negative), + (Add), (+ Concatenate), - (Subtract), & (Bitwise AND),^(Bitwise Exclusive OR), | (Bitwise OR) 
4  =, >, <, >=, <=, <>, !=, !>, !< (Comparison operators) 
5  NOT 
6  AND 
7  ALL, ANY, BETWEEN, IN, LIKE, OR, SOME 
8  = (Assignment) 

Was dies bedeutet ist, alle Ihre AND Aussagen zuerst ausgewertet werden. Nachdem sie alle ausgewertet wurden, wird Ihre OR-Anweisung ausgewertet.

Das macht Ihre Abfrage wie dies aussehen an den Compiler:

WHERE 
(
     inst_name = 'instance001' 
AND  LAST_READ IS NULL 
AND  LAST_WRITE IS NULL 
) 
OR  inst_name = 'instance002' 

Welche warum man 210 Ergebnisse wurden erhalten, in Bezug auf die 61 erwartet gegenüber, wie es in alle Aufzeichnungen in instance002 ziehen , ohne Ihre anderen WHERE Filter.

Umschreiben der Abfrage Gruppieren der beiden Bedingungen, wie oben erwähnt, wie dies stattdessen an den Compiler aussehen:

WHERE 
(
     LAST_READ IS NULL 
AND  LAST_WRITE IS NULL 
) 
AND  
(  
     inst_name = 'instance002' 
OR  inst_name = 'instance001' 
) 

, die die logischen Bedingungen sollten Sie erwarten.


Eine weitere Alternative Art und Weisen Sie diese Abfrage ohne die insgesamt Gruppierung AND/OR schreiben können, ist durch eine IN-Klausel:

... 
WHERE inst_name IN ('instance001', 'instance002') 
AND LAST_READ IS NULL 
AND LAST_WRITE IS NULL 
GROUP BY ... 
+0

noch alles nimmt in, aber mit dem zwickt ich bisher gemacht es scheint genau so zu funktionieren, wie es sollte! Ich werde morgen alles nochmal überprüfen müssen, aber das Ergebnis der Abfrage sieht momentan GROSS aus! Als Antwort markiert. :) – Erik