2013-09-24 7 views
5

Hallo jeder i in case-Anweisung verwenden möchten, diese Abfrage join mit und erhielt FehlerUse Case Statement in Join

Select CONVERT(VARCHAR(10), SII.SIDATE,103)DATE,SII.SALEID,SII.ItemName,SI.TenancyID 

FROM F_SALESINVOICEITEM SII 
INNER JOIN F_SALESINVOICE SI ON SI.SALEID=SII.SALEID 
INNER JOIN #TempTableSearch ts ON CASE 
WHEN ts.ACCOUNTTYPE = '1' THEN ts.ACCOUNTID=SI.TENANCYID 
    WHEN ts.ACCOUNTTYPE='2' THEN ts.ACCOUNTID=SI.EMPLOYEEID 
    WHEN ts.ACCOUNTTYPE='3' THEN ts.ACCOUNTID=SI.SUPPLIERID 
    WHEN ts.ACCOUNTTYPE='4' THEN ts.ACCOUNTID=SI.SALESCUSTOMERID 

Fehler

falsche Syntax in der Nähe von '='.

Bitte helfen Sie mir, diesen Fehler zu lösen.

Antwort

13

IT sollte,

ON 
ts.ACCOUNTID = CASE 
        WHEN ts.ACCOUNTTYPE = '1' THEN SI.TENANCYID 
        WHEN ts.ACCOUNTTYPE = '2' THEN SI.EMPLOYEEID 
        WHEN ts.ACCOUNTTYPE = '3' THEN SI.SUPPLIERID 
        WHEN ts.ACCOUNTTYPE = '4' THEN SI.SALESCUSTOMERID 
       END 
0

Sie haben Syntaxfehler. Sie vermissen dort END.

6

Statt Fall der Verwendung, ich würde viel lieber tun:

Select CONVERT(VARCHAR(10), SII.SIDATE,103)DATE,SII.SALEID,SII.ItemName,SI.TenancyID 
FROM F_SALESINVOICEITEM SII 
INNER JOIN F_SALESINVOICE SI ON SI.SALEID=SII.SALEID 
INNER JOIN #TempTableSearch ts ON 
     (ts.ACCOUNTTYPE='1' AND ts.ACCOUNTID=SI.TENANCYID) 
    OR (ts.ACCOUNTTYPE='2' AND ts.ACCOUNTID=SI.EMPLOYEEID) 
    OR (ts.ACCOUNTTYPE='3' AND ts.ACCOUNTID=SI.SUPPLIERID) 
    OR (ts.ACCOUNTTYPE='4' AND ts.ACCOUNTID=SI.SALESCUSTOMERID) 

Um zu erklären, warum die Abfrage nicht für Sie arbeiten: die Syntax des CASE ein END am Ende der Klausel erfordert . Es würde funktionieren, wie die anderen vorgeschlagenen Lösungen nahelegen, aber ich finde diese Version bequemer zu verstehen - obwohl dieser Teil sehr subjektiv ist.

+0

Sie haben die Abfrage ausgeführt, aber Sie haben nicht genau erklärt, was der Grund für einen Fehler war. – nimdil

1

Sie können dies tun, so haben Sie keine Chance, falsch schreiben etwas haben (beachten Sie, dass ACCOUNTTYPE und ACCOUNTID nur dann verwendet, wenn nötig, müssen Sie es nicht copy-paste)

select 
    convert(varchar(10), SII.SIDATE,103) as DATE, 
    SII.SALEID, SII.ItemName, SI.TenancyID 
from F_SALESINVOICEITEM as SII 
    inner join F_SALESINVOICE as SI on SI.SALEID = SII.SALEID 
    outer apply (
     '1', SI.TENANCYID 
     '2', SI.EMPLOYEEID 
     '3', SI.SUPPLIERID 
     '4', SI.SALESCUSTOMERID 
    ) as C(ACCOUNTTYPE, ACCOUNTID) 
    inner join #TempTableSearch as ts on 
     ts.ACCOUNTTYPE = C.ACCOUNTTYPE and ts.ACCOUNTID = C.ACCOUNTID 
0

Sie müssen verstehen, dass Block entspricht NICHT IF { } aus C-ähnlichen Sprachen. Viel eher entspricht dies einer ausgearbeiteten Version des ... ? ... : ... Operators aus C-ähnlichen Sprachen. Was es bedeutet, dass der GANZE CASE Block im Wesentlichen zu einem einzelnen Wert ausgewertet werden muss und dass dieser Wert vom selben Typ sein muss, egal welcher Fall des Blocks ausgeführt wird. Das bedeutet:

CASE 
WHEN ts.ACCOUNTTYPE = '1' THEN ts.ACCOUNTID=SI.TENANCYID ... 
END 

grundsätzlich falsch ist, wenn Sie auf einer Version der Datenbank arbeiten, die Sie Bool Wert als Wert (SQL Server ermöglicht wird es zum Beispiel nicht erlauben, aber ich denke, einige von MySQL-Version verwendet erlauben Sie es - nicht sicher darüber. Sie sollten wahrscheinlich so etwas wie schreiben:

CASE 
WHEN ts.ACCOUNTTYPE = '1' AND ts.ACCOUNTID=SI.TENANCYID THEN 1 
WHEN ts.ACCOUNTTYPE='2' AND ts.ACCOUNTID=SI.EMPLOYEEID THEN 1 
WHEN ts.ACCOUNTTYPE='3' AND ts.ACCOUNTID=SI.SUPPLIERID THEN 1 
WHEN ts.ACCOUNTTYPE='4' AND ts.ACCOUNTID=SI.SALESCUSTOMERID THEN 1 
ELSE 0 
END = 1 

Beachten Sie, wie der ganze CASE Block auf 1 oder 0 ausgewertet wird und dann wird es im Vergleich zu 1. Natürlich statt 4 WHEN ‚s Sie eine WHEN mit Kombination von AND verwenden könnten 's, OR' s und () Klammern. Natürlich ist in diesem speziellen Fall die Antwort von @ppeterka 66 korrekt, da CASE nicht für das geeignet ist, was Sie wirklich tun wollten - ich versuche nur zu klären, was CASE wirklich ist.