2016-12-09 4 views
3

Ich habe dies stundenlang angedockt und kann nicht mit einer "eleganten" Set-basierten Methode aufwarten, um die Ergebnismenge zu erhalten, die ich brauche. .Bedingte Auswahl von Zeilen mit TSQL SQL Server (2008 R2)

Hier ist mein Beispieldaten ...

DECLARE @t AS TABLE (ID int,ID1 nvarchar(15),[DATE] date,PERIOD int,[TYPE] nchar(1)); 

INSERT INTO @t (ID,ID1,[DATE],PERIOD,[TYPE]) 
VALUES 
(1,N'NUM1','2016-01-01',1,N'B'), 
(2,N'NUM1','2016-01-01',2,N'A'), 
(3,N'NUM1','2016-01-01',3,N'A'), 
(4,N'NUM1','2016-01-01',4,N'B'), 
(5,N'NUM1','2016-01-01',4,N'A'), 
(6,N'NUM1','2016-01-01',5,N'A'), 

(7,N'NUM1','2016-01-02',1,N'A'), 
(8,N'NUM1','2016-01-02',2,N'A'), 
(9,N'NUM1','2016-01-02',3,N'A'), 
(10,N'NUM1','2016-01-02',4,N'A'), 
(11,N'NUM1','2016-01-02',5,N'A'), 

(12,N'NUM2','2016-01-01',1,N'A'), 
(13,N'NUM2','2016-01-01',1,N'B'), 
(14,N'NUM2','2016-01-01',2,N'A'), 
(15,N'NUM2','2016-01-01',3,N'A'), 
(16,N'NUM2','2016-01-01',4,N'B'), 
(17,N'NUM2','2016-01-01',4,N'A'), 
(18,N'NUM2','2016-01-01',5,N'A'), 

(19,N'NUM2','2016-01-02',1,N'A'), 
(20,N'NUM2','2016-01-02',2,N'B'), 
(21,N'NUM2','2016-01-02',3,N'A'), 
(22,N'NUM2','2016-01-02',4,N'A'), 
(23,N'NUM2','2016-01-02',4,N'B'), 
(24,N'NUM2','2016-01-02',5,N'A'); 

Hier ist das Ergebnis Set zu bekommen ich versuche ...

1,'NUM1','2016-01-01',1,'B' 
2,'NUM1','2016-01-01',2,'A' 
3,'NUM1','2016-01-01',3,'A' 
5,'NUM1','2016-01-01',4,'A' 
6,'NUM1','2016-01-01',5,'A' 

7,'NUM1','2016-01-02',1,'A' 
8,'NUM1','2016-01-02',2,'A' 
9,'NUM1','2016-01-02',3,'A' 
10,'NUM1','2016-01-02',4,'A' 
11,'NUM1','2016-01-02',5,'A' 

12,'NUM2','2016-01-01',1,'A' 
14,'NUM2','2016-01-01',2,'A' 
15,'NUM2','2016-01-01',3,'A' 
17,'NUM2','2016-01-01',4,'A' 
18,'NUM2','2016-01-01',5,'A' 

19,'NUM2','2016-01-02',1,'A' 
20,'NUM2','2016-01-02',2,'B' 
21,'NUM2','2016-01-02',3,'A' 
22,'NUM2','2016-01-02',4,'A' 
24,'NUM2','2016-01-02',5,'A' 

(meine wirklichen Daten 1.000.000 Zeilen sein könnte) Einfach gesagt, jeder Tag hat 5 Perioden. Sie können vom Typ A oder B sein. Ich muss die A-Typen bekommen. aber wenn es keine A-Typen gibt, muss ich die B-Typen bekommen ... (Klingt so einfach, wenn ich es schreibe .., aber mein Gehirn wird nicht mit etwas passendes kommen)

Pleeeeeeease brachte mich raus mein Elend ..

+0

Ihre gewünschte Ausgabe nicht passen Sie Ihre Aussage des Problems an. Für jedes Datum gibt es 'A's, also gibt es kein Datum, für das du die' B's bekommen würdest. Ihre Ausgabe sollte nur 'A's haben? –

+0

Ich denke, er meint für jedes Datum und jede Periode –

Antwort

7

Sie können ROW_NUMBER für diesen Einsatz:

SELECT ID, ID1, [DATE], PERIOD, [TYPE] 
FROM (
    SELECT ID, ID1, [DATE], PERIOD, [TYPE], 
      ROW_NUMBER() OVER (PARTITION BY ID1, [DATE], PERIOD 
          ORDER BY [TYPE]) AS rn 
    FROM @t) AS t 
WHERE t.rn = 1 

mit ORDER BY [TYPE] in der OVER Klausel ROW_NUMBER Orte 'A' Aufzeichnungen auf von 'B' Aufzeichnungen. Wenn es keine 'A' Datensätze für eine gegebene ID1, [DATE], PERIOD gibt, dann werden B Datensätze zugewiesen rn = 1.

+0

Dies wird wahrscheinlich die schnellste der gegebenen Lösungen sein –

0

Ihre gewünschte Output widerspricht der Aussage, dass "ich die A-Typen bekommen muss. Aber wenn es keine A-Typen gibt, muss ich die B-Typen bekommen ...". Jedes Datum in den Daten hat einen oder mehrere A-Typen. Durch die Aussage sollte die Ausgabe nur die "A" -Typen enthalten. Aber wenn die Aussage korrekt ist, dann sollte diese Arbeit:

Select d.[DATE], t.Id, t.ID1, t.PERIOD, t.[TYPE] 
from (select distinct [date] from @t) d 
    left join @t t 
    on t.[date] = d.[date] 
    and t.type = case when exists 
     (select * from @t 
     where [date] = d.[Date] 
      and type = 'A') then 'A' 
      else 'B' End 
0

Ich habe gerade kommen mit

SELECT * FROM @t WHERE [TYPE]='A' 
    UNION ALL 
    SELECT * FROM @t t1 WHERE [TYPE]='B' AND NOT EXISTS (SELECT ID FROM @t WHERE ID1=t1.ID1 AND [TYPE]='A' AND [DATE]=t1.[DATE] AND Period=t1.Period) 
ORDER BY ID; 

, die mir geben, was ich brauche ...

Verwandte Themen