2017-11-08 4 views
0

Es müssen einige Spalten wie Jahre, Wochen, Schweregrad, Alarme und die gleichen Alarme wie zuvor angezeigt werden, nur gefiltert. Wie füge ich die letzte Spalte hinzu, die dieselbe wie vorher ist, nur mehr gefiltert?SQL Wie zeigt und gruppiert man zwei gleiche Spalten, von denen eine mehr gefiltert wird?

Beispiel:

SELECT 
CAST(DATEPART(yy, rSTA.FIRSTOCCURRENCEDAY) AS VARCHAR) AS YEAR, 
CAST(DATEPART(wk, rSTA.FIRSTOCCURRENCEDAY) AS VARCHAR) AS MONTH, 
rSEV.NAME AS SEVERITY, 
COUNT(rSTA.ALARMIDKEY) AS ALARMS 
FROM 
    REPORTER.reporter.REPORTER_STATUS rSTA 
INNER JOIN 
    REPORTER.reporter.REP_SEVERITY_TYPES rSEV 
    ON 
    rSTA.ORIGINALSEVERITY = rSEV.SEVERITY 
WHERE 
    rSTA.FIRSTOCCURRENCEDAY > DATEADD(week, -10, GETDATE()) 
    AND 
    rSEV.NAME != 'Clear' 
GROUP BY 
    DATEPART(yy, rSTA.FIRSTOCCURRENCEDAY), 
    DATEPART(wk, rSTA.FIRSTOCCURRENCEDAY), 
    rSEV.NAME 
ORDER BY 
    DATEPART(yy, rSTA.FIRSTOCCURRENCEDAY) DESC, 
    DATEPART(wk, rSTA.FIRSTOCCURRENCEDAY) DESC 

Diese Abfrage richtig erste 4 Spalten erzeugt, Anbringen Bild: ALARMS

Die fünfte Spalte die gleichen wie ALARM sein sollte, aber mit der Bedingung:

SELECT ALARMIDKEY AS ALARMS_CC FROM REPORTER.reporter.REPORTER_STATUS WHERE 
        (MAINTMODECRONTAB != 'Y' 
        AND SUPPRESSESCL < 4 
        AND SPMAUTO != 1 
        AND ORIGINALSEVERITY > 0) 
        AND ((AIWAVER = 3 AND EVENTACTOR = 1) 
          OR 
          ((AIWAVER < 3 OR AIWAVER IS NULL) 
          AND ((CONTROLCENTREVIEW = 1 
           AND ORIGINALSEVERITY = 5) 
           OR (CONTROLCENTREVIEW = 2) 
           OR (ALERTGROUP = 'CHECKLIST') 
           ) 
         ) 
         ) 

Jetzt frage ich mich, wie man diese Bedingung in die (erste) Hauptabfrage einfügt und gruppiert, um korrekte Daten zu erzeugen. Für jedes Jahr, Woche und Schweregrad zeigen Alarme und AlarmeCC (gleiche Spalte, nur unterschiedliche Bedingungen). Ich hoffe, dass es so aussehen würde:

Hoffe es macht es klar, was ich erreichen will. Wäre toll, wenn die Art und Weise, dies zu erreichen, mehr optimiert wäre. Vielleicht ist JOIN möglich?

+0

Sind Sie sicher, dass Sie benötigen Antworten auf zwei verschiedene Datenbanken? – Michas

+0

Dies ist die gleiche Datenbank, Jahr, Woche und Alarme befinden sich in der gleichen Tabelle. Der Schweregrad wird einer anderen Tabelle entnommen. – Robbac

+0

Sie haben die Frage sowohl mit Microsoft SQL Server als auch mit MySQL markiert. Dies sind zwei verschiedene relationale Datenbank-Management-Systeme. Brauchen Sie eine Antwort für beide? – Michas

Antwort

0

Sie konnten die additonal gefilterten Alarme erhalten, indem sie über eine Unterabfrage, wie diese Auswahl:

SELECT 
    CAST(DATEPART(yy, rSTA.FIRSTOCCURRENCEDAY) AS VARCHAR) AS YEAR, 
    CAST(DATEPART(wk, rSTA.FIRSTOCCURRENCEDAY) AS VARCHAR) AS MONTH, 
    rSEV.NAME AS SEVERITY, 
    COUNT(rSTA.ALARMIDKEY) AS ALARMS, 
    filtered.ALARMS_CC 
FROM REPORTER.reporter.REPORTER_STATUS rSTA 
INNER JOIN REPORTER.reporter.REP_SEVERITY_TYPES rSEV 
      ON rSTA.ORIGINALSEVERITY = rSEV.SEVERITY 
INNER JOIN (SELECT COUNT(ALARMIDKEY) AS ALARMS_CC, 
        DATEPART(yy, FIRSTOCCURRENCEDAY) AS year, 
        DATEPART(wk, rSTA.FIRSTOCCURRENCEDAY) AS month, 
        ORIGINALSEVERITY AS os 
      FROM REPORTER.reporter.REPORTER_STATUS 
      WHERE 
       (MAINTMODECRONTAB != 'Y' 
       AND SUPPRESSESCL < 4 
       AND SPMAUTO != 1 
       AND ORIGINALSEVERITY > 0) 
       AND ((AIWAVER = 3 AND EVENTACTOR = 1) 
         OR 
         ((AIWAVER < 3 OR AIWAVER IS NULL) 
         AND ((CONTROLCENTREVIEW = 1 
          AND ORIGINALSEVERITY = 5) 
          OR (CONTROLCENTREVIEW = 2) 
          OR (ALERTGROUP = 'CHECKLIST') 
          ) 
        ) 
        ) 
      GROUP BY DATEPART(yy, FIRSTOCCURRENCEDAY), 
        DATEPART(wk, rSTA.FIRSTOCCURRENCEDAY), 
        ORIGINALSEVERITY 
     ) AS filtered ON DATEPART(yy, rSTA.FIRSTOCCURRENCEDAY) = filtered.year AND 
          DATEPART(wk, rSTA.FIRSTOCCURRENCEDAY) = filtered.month AND 
          rSTA.ORIGINALSEVERITY = filtered.os 
WHERE 
    rSTA.FIRSTOCCURRENCEDAY > DATEADD(week, -10, GETDATE()) 
    AND 
    rSEV.NAME != 'Clear' 
GROUP BY 
    DATEPART(yy, rSTA.FIRSTOCCURRENCEDAY), 
    DATEPART(wk, rSTA.FIRSTOCCURRENCEDAY), 
    rSEV.NAME 
ORDER BY 
    DATEPART(yy, rSTA.FIRSTOCCURRENCEDAY) DESC, 
    DATEPART(wk, rSTA.FIRSTOCCURRENCEDAY) DESC 
+0

Es scheint tatsächlich zu funktionieren! Und wenn ich 54 statt 10 Wochen addiere, hat das keinen Einfluss auf die Zeit, um die Abfrage abzuschließen. Vielen Dank! – Robbac

1

Sie können versuchen, Fallanweisung in diesem Beitrag - How to count by filter in SQL query?.

So wird die Abfrage aussehen

SELECT 
     CAST(DATEPART(yy, rSTA.FIRSTOCCURRENCEDAY) AS VARCHAR) AS YEAR, 
     CAST(DATEPART(wk, rSTA.FIRSTOCCURRENCEDAY) AS VARCHAR) AS MONTH, 
     rSEV.NAME AS SEVERITY, 
     COUNT(rSTA.ALARMIDKEY) AS ALARMS, 

     SUM(CASE WHEN rSTA.MAINTMODECRONTAB != 'Y' 
          AND rSTA.SUPPRESSESCL < 4 
          AND rSTA.SPMAUTO != 1 
          AND rSTA.ORIGINALSEVERITY > 0) 
          AND ((rSTA.AIWAVER = 3 AND rSTA.EVENTACTOR = 1) 
            OR 
            ((rSTA.AIWAVER < 3 OR rSTA.AIWAVER IS NULL) 
            AND ((rSTA.CONTROLCENTREVIEW = 1 
             AND rSTA.ORIGINALSEVERITY = 5) 
             OR (rSTA.CONTROLCENTREVIEW = 2) 
             OR (rSTA.ALERTGROUP = 'CHECKLIST') 
             ) 
           )) 
        THEN 1 
        ELSE 0 END) AS ALARMS_CC 
    FROM 
     REPORTER.reporter.REPORTER_STATUS rSTA 
    INNER JOIN 
     REPORTER.reporter.REP_SEVERITY_TYPES rSEV 
     ON 
     rSTA.ORIGINALSEVERITY = rSEV.SEVERITY 
    WHERE 
     rSTA.FIRSTOCCURRENCEDAY > DATEADD(week, -10, GETDATE()) 
     AND 
     rSEV.NAME != 'Clear' 
    GROUP BY 
     DATEPART(yy, rSTA.FIRSTOCCURRENCEDAY), 
     DATEPART(wk, rSTA.FIRSTOCCURRENCEDAY), 
     rSEV.NAME 
    ORDER BY 
     DATEPART(yy, rSTA.FIRSTOCCURRENCEDAY) DESC, 
     DATEPART(wk, rSTA.FIRSTOCCURRENCEDAY) DESC 

UPDATE

ich eine optimierte Abfrage unten bin hinzugefügt wird.

WITH REPORTER_STATUS_FILTERED AS 
    (
     SELECT ALARMIDKEY 
     FROM REPORTER.reporter.REPORTER_STATUS 
     WHERE MAINTMODECRONTAB != 'Y' 
      AND SUPPRESSESCL < 4 
      AND SPMAUTO != 1 
      AND ORIGINALSEVERITY > 0) 
      AND ((AIWAVER = 3 AND EVENTACTOR = 1) 
       OR 
       ((AIWAVER < 3 OR AIWAVER IS NULL) 
       AND ((CONTROLCENTREVIEW = 1 
         AND ORIGINALSEVERITY = 5) 
        OR (CONTROLCENTREVIEW = 2) 
        OR (ALERTGROUP = 'CHECKLIST') 
        ) 
       )) 
    ) 

    SELECT 
     CAST(DATEPART(yy, rSTA.FIRSTOCCURRENCEDAY) AS VARCHAR) AS YEAR, 
     CAST(DATEPART(wk, rSTA.FIRSTOCCURRENCEDAY) AS VARCHAR) AS MONTH, 
     rSEV.NAME AS SEVERITY, 
     COUNT(rSTA.ALARMIDKEY) AS ALARMS, 
     COUNT(rSTA1.ALARMIDKEY) AS ALARMS_CC 
    FROM 
     REPORTER.reporter.REPORTER_STATUS rSTA 
    INNER JOIN 
     REPORTER.reporter.REP_SEVERITY_TYPES rSEV 
     ON 
     rSTA.ORIGINALSEVERITY = rSEV.SEVERITY 
    LEFT JOIN 
     REPORTER_STATUS_FILTERED rSTA1 
     ON 
     rSTA.ALARMIDKEY = rSTA1.ALARMIDKEY 
    WHERE 
     rSTA.FIRSTOCCURRENCEDAY > DATEADD(week, -10, GETDATE()) 
     AND 
     rSEV.NAME != 'Clear' 
    GROUP BY 
     DATEPART(yy, rSTA.FIRSTOCCURRENCEDAY), 
     DATEPART(wk, rSTA.FIRSTOCCURRENCEDAY), 
     rSEV.NAME 
    ORDER BY 
     DATEPART(yy, rSTA.FIRSTOCCURRENCEDAY) DESC, 
     DATEPART(wk, rSTA.FIRSTOCCURRENCEDAY) DESC 
+0

Ja, es scheint mit 10 Wochen zu funktionieren, wenn ich 54 Wochen setze, dauert es ziemlich lange. Frage mich, ob es optimiert werden kann oder so ist? – Robbac

+0

Ich habe die Antwort mit einem optimierten aktualisiert. Kannst du das bitte versuchen? – Manu

0
select YEAR, MONTH, SEVERITY, ALARMS, ALARMS_CC 
from (Q1) as T1 left join (Q2) as T2 on 
T1.YEAR = T2.YEAR 
and T1.MONTH = T2.MONTH 
and T1.SEVERITY = T1.SEVERITY 
ORDER BY YEAR DESC, MON DESC 

Wo Q1 Ihre Abfrage ohne Auftrag von Abschnitt ist und Q2 ist erste Abfrage mit zusätzlichen Bedingungen und letzten Spalten_Name geändert. Es ist wichtig, Q1, Q2 in Klammern() zu setzen.

Verwandte Themen