2016-04-08 13 views
-1

Ich habe eine Tabelle mit Spalten wie sourceId (guid), Zustand (1: Deaktiviert, 2: Aktiviert, 3: Dead), modifiedDate.SQL Gruppe von und wo auf jeder Gruppe

ich eine Anfrage an Gruppe von sourceId schreiben und sehen, ob alle Datensätze in einer Gruppe, die den Zustand haben, wie 2 (aktiviert) und die MAX von ModifiedDate der Reihen erhalten, den Staat als 2 haben (aktiviert) in jeder Gruppe.

Ergebnistabelle sollte etwas wie sourceId, IsAllActivated, MaxModifiedForActivatedRecords sein.

Ich habe versucht eine Menge Optionen wie Partition By, Cross over etc., die mir entweder eine der Spalte und nicht beide geben. Optionen, die Self-Joins haben, waren kostspielig und suchten nach einer anderen effizienten Möglichkeit zur Bildung der Abfrage.

Daten:

SourceId | Staat | modifiedDate

s1 | 1 | 01/01

s1 | 2 | 01/02

s2 | 3 | 02/03

s2 | 3 | 03/03

s1 | 3 | 10/10

Ouput:

sourceId | IsAllActivated | MaxModifiedForActivatedRecords

s1 | 0 | 02/03

s2 | 1 | 03.03

Was ich versucht hatte:

SELECT 
[SourceID] 
,CASE 
    WHEN COUNT(DISTINCT State) = 1 AND 
    SUM(DISTINCT State) = 3 
    THEN 1 
    ELSE 0 
END AS IsAllActivated 
FROM ThreadActivation 
GROUP BY SourceID 

SELECT 
[SourceID] 
,MAX(modifiedDate) AS MaxModifiedForActivatedRecords 
FROM ThreadActivation 
GROUP BY SourceID 
HAVING State = 3 

Ich bin in der Lage, sie getrennt zu bekommen, aber nicht zusammen in einer einzigen Abfrage.

Ich habe versucht, mit Zeilennummer Ranking:

WITH ThreadActivationTransaction AS (
     select 
     * 
     ,ROW_NUMBER() over(PARTITION BY SourceId order by modifiedDate desc) AS rk 
     from ThreadActivation) 
     select 

     [sourceID] 
     ,CASE 
      WHEN COUNT(DISTINCT State) = 1 AND SUM(DISTINCT State) = 3 
      THEN 1 
      ELSE 0 
     END AS IsAllActivated 
     ,[SourceId] 
    from ThreadActivation s 
     GROUP by SourceId --where s.rk =1 

Alle diese mir keine Pause durch gaben.

+0

Bitte geben Sie einige Beispieldaten und das erwartete Ergebnis an. –

+0

Es tut mir leid, ich bin neu im Forum und ich bin nur ein paar Fragen alt. Ich hatte viel versucht, bevor ich in die Gemeinde kam, um eine Lösung zu finden. Ich hatte nicht die Absicht, die Antworten ohne angemessene Forschungsanstrengungen zu bekommen. – AdCan

+0

Ich würde gerne mehr wissen, wenn es eine andere effiziente Möglichkeit gibt, dies auch zu tun @KenWhite – AdCan

Antwort

6

Sie können dies mit Aggregation und case:

select sourceId, 
     (case when max(state) = min(state) and max(state) = 2 
      then 1 else 0 
     end) as IsAllActivated, 
     max(case when state = 2 then modifiedDate end) as MaxModifiedForActivatedRecords 
from t 
group by sourceId; 

Dies setzt voraus, dass state ist nicht NULL. Die Logik ist nur etwas komplizierter, wenn das möglich ist.

+0

So cool ..! Ich weiß nicht, dass wir einen CASE in MAX machen können. Ich danke dir sehr. – AdCan

+0

Sag, wenn ich nach einer Flagge namens IsAllDead suche (was bedeutet, dass ich suche, ob alle Threads in einer Gruppe tot sind - gruppiert nach SourceID), kann es nicht nur min (state) = 3 statt max (state) sein = min (Zustand) und max (Zustand) = 3 – AdCan