2016-07-30 8 views
0

Ich habe diese Frage. Lassen Sie uns die Abfrage sehen:SQL Server bedingte Abfrage für ein Master-Detail Abfrageergebnis

Dies ist eine typische Master-Detail-Tabelle (Document-DocumentVersion). A Document kann einen oder mehrere DocumentVersions oder keine haben. Ein DocumentVersion-Status kann PUBLISHED oder UNPUBLISHED sein. Die PUBLISHED eine DocumentVersion kann nur einmal für eine Document existieren (dies wird von der Anwendung gesteuert), aber es gibt viele UNPUBLISHED, oder alle DocumentVersions sind UNPUBLISHED. NICHT PUBLISHED existiert nicht, es ist nur ein Wort im Abfrageergebnis, wenn es keinen DocumentVersion Datensatz für eine Document gibt, das ist der Grund für die LEFT JOIN.

Also meine Frage ist: Wie kann ich die Abfrage die nächsten Regeln ausführen lassen?

  • Wenn ein DocumentVersion Zustand PUB ist, ignorieren die anderen, ich meine, zeigen nicht die UNP diejenigen im Abfrageergebnis für diese Document

  • Wenn ein DocumentVersion Zustand ist UNP (und hier kann sein viele UNP), zeigen dann nur die mit dem höchsten Datum Unpublish (DocumentVersion Tabelle hat eine UnPublishDate Spalte), diese Regel nur gilt, wenn es keine PUBDocumentVersion für das Dokument ist

Ich würde mich über jede Hilfe freuen, die Sie mir geben können, danke Jungs.

Antwort

0

Dies ist eine Priorisierungsanfrage. Sie können es row_number() oder rank() mit tun:

select d.*, dv.* 
from d left join 
    (select dv.*, 
      row_number() over (partition by dv.IdDocument 
           order by (case when dv.state = 'PUB' then 1 
               when dv.state = 'UNP' then 2 
               else 3 
              end) 
           ) as seqnum 
     from documentversion dv 
    ) dv 
    on dv.IdDocument = d.IdDocument and 
     seqnum = 1; 

Hinweis: Ich glaube nicht, die Join-Bedingung in Ihrer Frage richtig ist.

+0

Mit Ihrem Ansatz zeigt der 'UNP' den Status mit dem niedrigsten UnPublishedDate und ich brauche den höchsten, außerdem brauche ich die Fälle, wenn DocumentVersion für ein Dokument nicht existiert, aus diesem Grund benutze ich den LEFT JOIN. –

+0

Oh, ich glaube, Gordon hat gerade '' UnPublishDate desc 'vom Ende seiner Bestellung verpasst und musste stattdessen einen linken Outer Join machen. Meine Abfrage ist ziemlich gleich –

+0

@VorpulusLyphane. . . Vielen Dank. –

1
select * 
from Document D 
left outer join 
    (select *, 
    row_number()over(partition by IdDocumentVersion order by state asc, UnPublishDate desc) as row 
    from DocumentVersion) V 
on D.IdDocument = V.IdDocumentVersion 
and V.row = 1 

State Asc ist übrigens ein bisschen wie ein Hack, der gerade in diesem Fall funktioniert. Vielleicht möchten Sie expliziter mit einem "Fall wann" sein (siehe Gordons Antwort).

+0

Danke. habe das "UnPublishDate desc" mit dem Edit (@Gordon) hinzugefügt, das er macht und arbeitet, aber ich verstehe nichts, bitte sehen Sie meinen letzten Kommentar zu @Gordon. –

+0

Gordon hat es irgendwie geschafft, das Vorhandensein einer IdDocument-Spalte in Ihrer DV-Tabelle (diese Spalte erschien nirgendwo in Ihrer "Arbeits" -Abfrage) mit der Sicherheit vorauszusagen, dass er sie tatsächlich in seiner Antwort verwendet hat. Ich nahm an - fälschlicherweise -, dass Sie die Spalte, die die Dokument-ID repräsentiert, einfach als IDDocumentVersion bezeichnet haben. Mit anderen Worten, beide Abfragen sollten mit der gleichen Sache partitionieren: DocumentID.Sie partitionieren nach DocumentID, so dass Sie für jede DocumentID die Versionen in der Rangfolge der Präferenz ordnen können (PUB über UNP, dann spätere Version gegenüber früher) und die oberste nehmen. –

+0

Vielen Dank für Ihre Hilfe. –