2016-07-04 16 views
2

ich das unten stehende Abfrage ausgeführt wird:Alternativen zur Verwendung von IN-Klausel

SELECT 
    ReceiptVoucherId, 
    VoucherId, 
    ReceiptId, 
    rvtransactionAmount, 
    AmountUsed, 
    TransactionTypeId 
FROM 
    [Scratch].[dbo].[LoyaltyVoucherTransactionDetails] 
WHERE  
    VoucherId IN 
    (2000723, 
    2000738, 
    2000774, 
    2000873, 
    2000888, 
    2000924, 
    2001023, 
    2001038, 
    2001074, 
    2001173) 

das Ziel, die ReceiptVoucherId/VoucherId/ReceiptId/rvtransactionAmount/AmountUsed/TransactionTypeId Daten für die Liste der voucherId der zu extrahieren ist, dass ich habe.

Mein Problem ist, dass meine Liste der VoucherID des 187k lang ist so eine IN-Klausel nicht möglich ist, da sie den Fehler zurückgibt:

Interner Fehler: Ein Ausdruck Dienste Grenze

erreicht wurde, kann jemand rät zu einer Alternative dazu?

Ich bin mit SSMS 2014

+1

Verwenden Sie stattdessen eine temporäre Tabelle, um die Werte zu speichern –

+1

Wenn diese Gutschein-IDs irgendwo anders vorhanden sind, können Sie anstelle der tatsächlichen Werte auch eine Unterabfrage verwenden. Aber das in einer Tabelle wie @GiorgosBetsos gespeichert zu haben, wäre ein viel sauberer Ansatz. – Mfusiki

+2

Woher kommen diese 187K Werte * von *? Sie sind sicherlich keine feste Liste von Hand eingegeben? Und wohin gehen die Ergebnisdaten *? Es ist viel zu viel für jemanden, um diese Ergebnisse direkt zu konsumieren. Es fühlt sich an, als ob Sie vielleicht eine logische Einzelabfrage in mehrere Verfahrensschritte aufgeteilt haben, und dies ist einer der Zwischenschritte.Wenn wir die gesamten End-to-End-Anforderungen verstehen, können wir möglicherweise eine bessere Gesamtlösung anbieten. –

Antwort

1

Erstellen Sie einfach eine Tabelle, die alle diese Gutscheine, die (hoffentlich bereits vorhanden) und dann IN() Auswahl aus der Tabelle verwenden:

SELECT 
    ReceiptVoucherId, 
    VoucherId, 
    ReceiptId, 
    rvtransactionAmount, 
    AmountUsed, 
    TransactionTypeId 
FROM 
    [Scratch].[dbo].[LoyaltyVoucherTransactionDetails] 
WHERE  
    VoucherId IN (SELECT VoucherId FROM VourchersTable) 
+0

Abhängig von den Privilegien ist die Erstellung einer "echten" Tabelle nicht so einfach ... Ich denke die Tabvariable oder die Cte ​​könnte etwas einfacher sein, nein? – Tyron78

+0

Wenn er nicht die Privilegien hat, kann er einfach seinen DBA fragen. 'CTE' ist keine schlechte Idee, aber es ist für 190k Datensätze – sagi

+0

haha ​​UR Recht ... aber in einer Firma, die ich vor einigen Jahren zu arbeiten pflegte, würde der DBA glücklich den Finger auf dich drehen und dir sagen, ** aus. ;-) Sie können sehr böse werden, wenn es zu Privilegien kommt. :-) ABER du hast Recht - Wenn du etwas analysieren musst, solltest du die Privilegien haben. In Bezug auf die Anzahl der Datensätze: Ich habe kürzlich ein CTE mit etwa 300K verwendet und es funktionierte ganz gut ... aber ich benutzte ein Skript, um die Abfrage für mich zu spoolen. ;-) – Tyron78

0

Vielleicht folgende Arbeiten für Sie :

Zuerst deklarieren Sie eine Variable vom Typ Tabelle (oder alternativ eine temporäre Tabelle) und fügen Sie Ihre IDs ein. Ändern Ihre Frage an

WHERE VoucherID in (SELECT VoucherID FROM @t) 

Alternativ (aber ähnliche schreibintensive für Ihre Hände ;-)) ist die Schaffung eines CTE:

WITH cte AS (SELECT 2000723 UNION ALL SELECT ...) 

und wieder die Neugestaltung des „WHERE .. . Im Abschnitt.

+0

Die Schaffung eines CTE mit 187k Aufzeichnungen? Viel Glück . – sagi

0

Fügen Sie die Gutscheine ein, um in einer separaten Tabelle nachzuschlagen. Lassen Sie es Gutschein nennen.

Dann sollte diese Abfrage den Trick tun. Es tut nicht Verwenden Sie die IN-Klausel. Stattdessen verwendet es Inner join, das schneller sein wird.

SELECT 
    L.ReceiptVoucherId, 
    L.VoucherId, 
    L.ReceiptId, 
    L.rvtransactionAmount, 
    L.AmountUsed, 
    L.TransactionTypeId 
FROM 
    [Scratch].[dbo].[LoyaltyVoucherTransactionDetails] L 
INNER JOIN dbo.Vouchers V ON L.VoucherId = V.VoucherId 
0

Sie können den Ansatz versuchen:

select from mytable where id in (select id from othertable) 

oder links kommen:

select from othertable left join mytable using id 

nicht sicher, was eine bessere Leistung hat auch zweite Abfrage können Sie leere Zeilen geben, wenn dies nicht der Fall als Fremdschlüssel deklariert.

Fly-by-Post, fühlen Sie sich frei, es zu verbessern.