2017-01-15 8 views
3

bitte mich auf dieses Problem mit einer Lösung helfen ..Filter Zeilen basierend auf bestimmten Bedingungen

Tisch wie das ist -

Type | SubType | Flag | Value 
-------------------------------- 
123 | A1  | Y | 101 
-------------------------------- 
123 | A2  | Y | 102 
------------------------------ 
123 | A3  | Y | 103 
------------------------------ 
124 | A4  | N | 104 
------------------------------ 
124 | A5  | N | 105 
------------------------------ 
124 | A6  | N | 106 
------------------------------ 
125 | A7  | Y | 107 
------------------------------ 
125 | A8  | Y | 108 
------------------------------ 
125 | A9  | N | 109 
------------------------------ 
125 | A10 | N | 110 

Voraussetzung ist, um Zeilen auszuwählen, basierend auf bestimmten Bedingungen - , wenn alle Flags sind Y für einen bestimmten Typ. Wählen Sie dann nur die Zeile mit dem niedrigsten Subtyp, , wenn alle Flags N für einen bestimmten Typ sind. Wählen Sie dann alle Zeilen dieses Typs , wenn Flags für einen Typ eine Kombination aus Y und N sind dieser Typ - einer mit dem niedrigsten Subtyp von Flag Y und einer mit dem niedrigsten Subtyp e der Flagge N.

So soll die Ausgabe von obiger Tabelle aussehen -

Type | SubType | Flag | Value 
------------------------------ 
123 | A1  | Y | 101 
------------------------------ 
124 | A4  | N | 104 
------------------------------ 
124 | A5  | N | 105 
------------------------------ 
124 | A6  | N | 106 
------------------------------ 
125 | A7  | Y | 107 
------------------------------ 
125 | A9  | N | 109 

Sorry für schlechte Tabellenformate, Vielen Dank im Voraus für die in diesen suchen.

Antwort

1

Sie können von Fensterfunktionen wie diese machen:

with your_table (Type , SubType , Flag , Value) as (
select 123 , 'A1'  , 'Y' , 101 union all 
select 123 , 'A2'  , 'Y' , 102 union all 
select 123 , 'A3'  , 'Y' , 103 union all 
select 124 , 'A4'  , 'N' , 104 union all 
select 124 , 'A5'  , 'N' , 105 union all 
select 124 , 'A6'  , 'N' , 106 union all 
select 125 , 'A7'  , 'Y' , 107 union all 
select 125 , 'A8'  , 'Y' , 108 union all 
select 125 , 'A9'  , 'N' , 109 union all 
select 125 , 'A10' , 'N' , 110) 

select Type, SubType, Flag, Value 
from (
    select 
    t.*, 
    case when min(flag) over (partition by type) = max(flag) over (partition by type) then 1 else 2 end cnt, 
    row_number() over (partition by type, flag order by convert(int, substring(subtype,2,len(subtype)))) rn 
    from your_table t 
) t where 
(cnt = 1 and (rn = 1 or flag = 'N')) 
or (cnt <> 1 and rn = 1); 

Produziert:

enter image description here

+2

Das wird nicht funktionieren, weil 'Verwendung von DISTINCT mit der OVER clause' ist nicht erlaubt. – Serge

+0

Dank GurV, versuchte mit deutlichen entfernen und in der Partition mit nach wie diesem, aber es würde nicht wieder die ganze Art 124 (Zustand 2) ---- select * aus ( wählen t. *, count (flag) über (Partition nach Typ, Flag) cnt, row_number() über (Partition nach Typ, Flag nach Subtyp sortiert) rn von your_table t ) t wo (cnt = 1 und (rn = 1 oder flag = ' N ')) oder (cnt <> 1 und rn = 1); – rai01

1

einen CTE Verwenden Sie eine Zusammenfassung für jeden Typ zu erzeugen, dann filtern darauf:

WITH summary AS (

     SELECT [Type] 

       ,SUM(CASE WHEN [Flag] = 'Y' THEN 1 ELSE 0 END) AS Count_Y 
       ,SUM(CASE WHEN [Flag] = 'N' THEN 1 ELSE 0 END) AS Count_N 

       -- This value will be NULL, if there are no rows with Y flag 
       ,MIN(CASE WHEN [Flag] = 'Y' THEN CAST(SUBSTRING(SubType,2,99) AS INT) END) AS Lowest_Y_SubType 
       -- This value will be NULL, if there are no rows with N flag 
       ,MIN(CASE WHEN [Flag] = 'N' THEN CAST(SUBSTRING(SubType,2,99) AS INT) END) AS Lowest_N_SubType 
     FROM dbo.tSO_41657760 
     GROUP BY [Type] 

) 
SELECT * 
FROM dbo.tSO_41657760 t 
WHERE EXISTS (
     SELECT 1 
     FROM summary 
     -- Filter this inner table using Type from the outer table 
     WHERE [Type] = t.[Type] 
     AND 
     (
     -- All rows have N flag 
     (Count_Y = 0) 
     -- Select the lowest N and Y rows with lowest SubType values 
     OR (CAST(SUBSTRING(SubType,2,99) AS INT) IN (Lowest_N_SubType, Lowest_Y_SubType)) 
     ) 
) 

Im obigen Code extrahieren wir die Ziffern von SubType nach richtig sortieren. Dies stellt sicher, dass A9kleiner alsA10 ist (sonst führt eine einfache alphabetische Sortierung zu falschen Ergebnissen).

+0

Ich denke, wir können "Value" für die Bestellung der Datensätze anstelle von "Untertyp" verwenden. Gute Lösung +1 –

+0

Dank Serge, bitte beachten Sie, dass Spalte Subtyp kann alphanumerische oder alphanumerische Werte haben ..... so extrahieren die Ziffern wäre nicht möglich – rai01

+0

Ich könnte anwenden, min nach dem Generieren Reihe Nummer auf Subtype basiert, aber das scheint nicht zu sein eine gute Lösung insgesamt – rai01

1

Hier ist ein Weg,

;WITH cte 
    AS (SELECT Count(1)OVER(partition BY [Type]) cnt,* 
     FROM (SELECT DISTINCT [Type], 
           [Flag], 
           -- to find the first record when flag is Y 
           Min([Value])OVER(partition BY [Type])   AS min_val, 
           -- to find the first records of Flag Y and N for each type 
           Min([Value])OVER(partition BY [Type], [Flag]) AS min_fl_val 
       FROM Yourtable) a) 
SELECT * 
FROM Yourtable a 
WHERE EXISTS (SELECT 1 
       FROM cte b 
       WHERE a.Type = b.Type 
         AND ((cnt = 1 
           AND Flag = 'y' 
           AND b.min_val = a.Value) -- to find first record of Type when Flag is only Y 
          OR (cnt = 1 
            AND Flag = 'N') -- to pull all the record of Type when Flag is only N 
          OR (cnt > 1 
            AND a.Flag = b.Flag 
            AND a.Value = b.min_fl_val))) -- to find first record for each flag in each type 
+0

Dank Prdp, Bestellung muss mit Subtype nur unter Berücksichtigung, dass es alphanumerische und alphanumerische Typen haben kann getan werden. – rai01

+0

@ rai01 - Also, wie finden Sie den ersten Datensatz ist es nur alphanumerische Reihenfolge oder Sie haben eine Logik für die Bestellung? –

+0

Alphanumerische Reihenfolge ist erforderlich ... – rai01

Verwandte Themen