2017-09-22 4 views
0

Zunächst entschuldigen Sie, wenn diese Frage (meine erste in Stackoverflow) ein Duplikat ist und ich konnte es nicht finden. Ich bin brandneu und lerne immer noch die Seile.TSQL: So wählen Sie einen Bereich basierend auf mehreren Spalten

Ich habe eine Tabelle mit 4 Spalten:

C1 C2 C2 C4 
------------------- 
1 11 111 1111 
1 11 222 1111 
1 22 222 2222 
1 22 444 2222 
1 33 444 3333 
2 22 333 2222 
2 33 333 3333 
2 33 333 4444 

2 44 444 1111 -- start range 
2 44 444 4444 
3 11 111 2222 
3 11 222 2222 -- end range 

3 22 333 2222 
3 22 444 2222 
4 11 111 4444 
4 11 222 1111 
4 44 222 2222 
4 44 333 1111 

Wie kann ich alle Zeilen wählen außerhalb „Startbereich“ und „End-Bereich“?

Die Art, wie ich es mache, ist dies, aber ich frage mich, ob es einen besseren Weg gibt?

select * from Table1 

where 
    -- start range 
    Col1 < 2 
    or 
    Col1 = 2 and Col2 < 44 
    or 
    Col1 = 2 and Col2 = 44 and Col3 < 444 
    or 
    Col1 = 2 and Col2 = 44 and Col3 = 444 and Col4 < 1111 
    -- end range 
    or 
    Col1 > 3 
    or 
    Col1 = 3 and Col2 > 11 
    or 
    Col1 = 3 and Col2 = 11 and Col3 > 222 
    or 
    Col1 = 3 and Col2 = 11 and Col3 = 222 and Col4 > 2222 

Ich möchte klarstellen, dass ich das, was ich nach, ob es eine Möglichkeit, alle all jene „oder“ Bedingungen zu vermeiden ist; so etwas wie MySQL tut es mit:

where (Col1, Col2, Col3, Col4) < (2, 44, 444, 1111) or (Col1, Col2, Col3, Col4) > (3, 11, 222, 2222)

Auch ein paar zusätzliche Punkte:

  • Die 4 Säulen sind einzigartige Kombinationen (man stelle sich einen Primärschlüssel über alle 4 Spalten);
  • Ich habe keine Kontrolle über die Struktur der Tabelle, das ist, was ich bekomme;
  • Die Anzahl der Spalten ist beliebig (ich muss die TSQL
    programmgesteuert generieren);
  • Die Daten, die ich gezeigt habe, sind nur für die Frage, die realen Daten sind komplexer.
+0

Ich denke, vielleicht müssen Sie Ihr Datenmodell verbessern, so dass Sie einzelne Zahlen und nicht die Fragmente auf getrennte Spalten zu speichern. Abgesehen von der Schwierigkeit, die Abfrage zu erschweren, macht es Ihr aktuelles Design möglicherweise schwieriger, einen Index zu verwenden. –

+1

Kann Außer Operator verwenden – Paparazzi

+0

@Paparazzi Dang schlug mich dazu – djangojazz

Antwort

0

Ich würde eine Ausnahme Operator tun (wie Paparazzi bereits erwähnt)

Select * 
from YourTable 
Except 
select * 
from YourTable 
where (C1 = 2 and C2 >= 44 and C3 >= 444 and C4 >= 1111) 
    or (C1 = 3 and C2 >= 11 and C3 <= 222 and C4 <= 2222) 
+0

Vielen Dank für die Antwort, ich sehe, dass Sie nur C1 und C2 überprüfen, die in diesem Fall funktionieren würde. Zur Klarstellung müssen alle Spalten als nächste Zeile nach dem Bereich geprüft werden (3, 11, 333, 2222) und ausgewählt werden. – Francesco

+0

Aktualisiert, das Problem, wirklich zu verstehen, sollte sein, dass ich für das Set jagen Sie wollen für alles unter dem "Ausgenommen" ausschließen und dann den gesamten Satz darüber verwenden. Sie können alle Prädikate für Ihre Qualifikationen ändern. Ich habe das Prädikat so kurz wie möglich für das gemacht, was ich dachte. Ich habe es etwas aktualisiert, um Ihren Bedürfnissen besser gerecht zu werden. – djangojazz

Verwandte Themen