2017-02-25 3 views
-2

Verbrachten eine Weile auf diese noch nicht ganz verstanden. Ich habe ein paar Zeilen in einer Tabelle wie folgt aus:Wie kann ich diese SQL Server-Abfrage schreiben?

uuid, pos (R|S|N), number (1-10), account (string), xtype (string) 

Eine einzigartige Reihe wird durch uuid, pos, Nummer identifiziert

ich eine Abfrage zu schreiben, ich versuche, das Vorkommen von finden:

  • gleiche UUID wo
    • account = x, pos = R, Anzahl = 1
    • account = x, pos = S, nu mber = 1
    • keine Vorkommen von pos N
    • pos R hat nur eine Zeile mit der Nummer 1, keine anderen Vorkommen von po R für diesen UUID

Hoffe, dass ich genug Informationen zur Verfügung gestellt haben, bitte Lass es mich wissen, wenn du mehr brauchst.

+1

Können Sie posten Sie die Abfrage Sie sind tr ying? –

+1

Beispieldaten wie DDL + DML und gewünschte Ergebnisse würden helfen, diese (und andere) SQL-Frage zu beantworten. Außerdem, mit welcher Version von SQL Server arbeiten Sie? –

Antwort

1

Sie sind für UUIDs die Datensätze, von denen entsprechen bestimmten Bedingungen suchen. Sie aggregieren also pro UUID (d. H. GROUP BY).

select uuid 
from mytable 
group by uuid 
having count(case when account = 'x' and pos = 'R' and number = 1 then 1 end) > 0 
    and count(case when account = 'x' and pos = 'S' and number = 1 then 1 end) > 0 
    and count(case when pos = 'N' then 1 end) = 0 
    and count(case when pos = 'R' and number <> 1 then 1 end) = 0; 

(Naja, eigentlich mit uuid + pos eindeutig ist, können Sie die letzte Bedingung entfernen, wie es in der ersten enthalten ist, und Sie können > 0-= 1 ändern, wenn Sie dies deutlicher finden.)

0

Sind Sie nach einer Abfrage, um Instanzen von Uuid-Werten zu finden, die verschiedene Zeilen in Ihrer Tabelle haben, die alle vier Bedingungen erfüllen?

Sie könnte entweder CTE verwenden:

with c1 (uuid) 
    as (select uuid from myTable where account = 'x' and pos = 'R' and number = 1), 
    c2 (uuid) 
    as (select uuid from myTable where account = 'x' and pos = 'S' and number = 1), 
    c3 (uuid) 
    as (select uuid from myTable where pos = 'N'), 
    c4 (uuid) 
    as (select uuid from myTable where pos = 'R' and number <> 1) 

select distinct myTable.uuid 
from myTable 
    inner join c1 on myTable.uuid = c1.uuid 
    inner join c2 on myTable.uuid = c2.uuid 
    left join c3 on myTable.uuid = c3.uuid 
    left join c4 on myTable.uuid = c4.uuid 
where c3.uuid IS NULL and c4.uuid IS NULL 

Oder Sie könnten exists verwenden:

select distinct uuid from myTable t 
where exists (select 1 from myTable where uuid = t.uuid and account = 'x' and pos = 'R' and number = 1) 
    and exists (select 1 from myTable where uuid = t.uuid and account = 'x' and pos = 'S' and number = 1) 
    and not exists (select 1 from myTable where uuid = t.uuid and pos = 'N') 
    and not exists (select 1 from myTable where uuid = t.uuid and pos = 'R' and number <> 1) 
0

Eine Möglichkeit, es zu tun bedingte Aggregation verwendet, und die über Klausel:

erstellen und füllt Beispieltabelle (Bitte speichern uns diesen Schritt in Ihren zukünftigen Fragen)

DECLARE @T AS TABLE 
(
    uuid int, 
    pos char(1), 
    Number tinyint, 
    Account varchar(3), 
    xtype char(1) 
) 

INSERT INTO @T VALUES 
(1, 'R', 1, 'abc', 'a'), 
(1, 'S', 1, 'def', 'b'), 
(1, 'N', 1, 'ghi', 'c'), 
(1, 'R', 2, 'jkl', 'd'), 
(2, 'R', 1, 'mno', 'e'), 
(2, 'S', 1, 'pqr', 'f'), 
(2, 'N', 1, 'stu', 'g'), 
(3, 'R', 1, 'vwx', 'h'), 
(3, 'S', 1, 'yz', 'i') 

Der CTE Spalten uns sagen, wenn die Bedingungen erfüllt sind enthalten:

;WITH CTE AS 
(
    SELECT uuId, 
      pos, 
      Number, 
      Account, 
      xtype, 
      SUM(CASE WHEN pos = 'R' AND Number > 1 THEN 1 ELSE 0 END) OVER(PARTITION BY uuId) As WrongR, 
      SUM(CASE WHEN pos = 'N' THEN 1 ELSE 0 END) OVER(PARTITION BY uuId) As NExists, 
      SUM(CASE WHEN pos = 'R' AND Number = 1 THEN 1 ELSE 0 END) OVER(PARTITION BY uuId) As RightR, 
      SUM(CASE WHEN pos = 'S' AND Number = 1 THEN 1 ELSE 0 END) OVER(PARTITION BY uuId) As RightS 
    FROM @T 
) 

Abfrage der CTE:

SELECT uuId, 
     pos, 
     Number, 
     Account, 
     xtype 
FROM CTE 
WHERE WrongR = 0 
AND NExists = 0 
AND RightR = 1 
AND RightS = 1 

Ergebnisse:

uuId pos  Number Account  xtype 
3  R  1  vwx   h 
3  S  1  yz   i  
0
select uuid from table where account = x and pos = R and number = 1 
intersect 
select uuid from table where account = x and pos = S and number = 1 
except 
select uuid from table where     pos = N 
except 
select uuid from table where     pos = R and number <> 1