web-dev-qa-db-ja.com

入れ子になったSELECTクエリとLEFT OUTER JOINと組み合わせたUPDATE

入れ子になったSELECTステートメントをLEFT OUTER JOINステートメントと組み合わせて含むUPDATEステートメントに問題があります。

状況:私たちのデータベースでは、データベースにいるすべての人に新しい列が追加されています。特定の人の列を値「X」で更新しますが、特定の条件のある人にのみ更新します。

次のSELECTステートメントを使用して、この列を更新する必要があるすべてのユーザーを正常に選択します。更新したいカラムは「テストフィールド」です

SELECT
    TESTDB.CONTACT.number2 AS CustomerID,
    TESTDB.PERSON.firstname AS FirstName,
    TESTDB.PERSON.lastname AS LastName,
    (SELECT UPPER(string19) FROM TESTDB.UDPERSONSMALL WHERE TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.UDPERSONSMALL_id) AS Testfield
FROM         
    TESTDB.CONTACT 
    LEFT OUTER JOIN TESTDB.PERSON ON TESTDB.CONTACT.contact_id = TESTDB.PERSON.contact_id
    LEFT OUTER JOIN TESTDB.UDPERSONSMALL ON TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.udpersonSmall_id 
    LEFT OUTER JOIN TESTDB.UDCONTACTLARGE ON TESTDB.CONTACT.userdef2_id = TESTDB.UDCONTACTLARGE.udcontactLarge_id
WHERE 
    (TESTDB.CONTACT.contact_id = TESTDB.PERSON.contact_id) 
/*  No retired people*/
    AND TESTDB.PERSON.retired = '0'
/*  Other conditions*/
    AND ((SELECT UPPER(string05) FROM TESTDB.UDPERSONSMALL WHERE TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.UDPERSONSMALL_id) = 'A'
    OR  (SELECT UPPER(string07) FROM CRM5.UDPERSONSMALL WHERE TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.UDPERSONSMALL_id) = 'B'
    OR  (SELECT UPPER(string08) FROM CRM5.UDPERSONSMALL WHERE TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.UDPERSONSMALL_id) = 'C')
/*  testpersonen*/
    AND (SELECT string45 FROM TESTDB.UDPERSONLARGE WHERE TESTDB.PERSON.userdef2_id = TESTDB.UDPERSONLARGE.UDPERSONLARGE_id) = '123'
ORDER BY
    CustomerID, FirstName, LastName

出力:

10001;Test1;Person1;
10001;Test2;Person2;
10001;Test3;Person3;
10001;Test4;Person4;
10001;Test6;Person6;
10001;Test7;Person7;
10001;Test8;Person8;

(7 rows affected)

これは正解です。現時点では、人々はTestfieldで値NULLを持っています。 (4番目の列は空です)

ここで、列「Testfield」を更新し、これまでこれを試しました。

UPDATE
    TESTDB.CONTACT 
    LEFT OUTER JOIN TESTDB.PERSON ON TESTDB.CONTACT.contact_id = TESTDB.PERSON.contact_id
    LEFT OUTER JOIN TESTDB.UDPERSONSMALL ON TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.udpersonSmall_id 
    LEFT OUTER JOIN TESTDB.UDCONTACTLARGE ON TESTDB.CONTACT.userdef2_id = TESTDB.UDCONTACTLARGE.udcontactLarge_id
SET
    (SELECT UPPER(string19) FROM TESTDB.UDPERSONSMALL WHERE TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.UDPERSONSMALL_id) = 'J'
WHERE 
    (TESTDB.CONTACT.contact_id = TESTDB.PERSON.contact_id) 
/*  No retired people*/
    AND TESTDB.PERSON.retired = '0'
/*  Other conditions*/
    AND ((SELECT UPPER(string05) FROM TESTDB.UDPERSONSMALL WHERE TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.UDPERSONSMALL_id) = 'A'
    OR  (SELECT UPPER(string07) FROM TESTDB.UDPERSONSMALL WHERE TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.UDPERSONSMALL_id) = 'B'
    OR  (SELECT UPPER(string08) FROM TESTDB.UDPERSONSMALL WHERE TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.UDPERSONSMALL_id) = 'C')
/*  testpersonen*/
    AND (SELECT string45 FROM TESTDB.UDPERSONLARGE WHERE TESTDB.PERSON.userdef2_id = TESTDB.UDPERSONLARGE.UDPERSONLARGE_id) = '123'

しかし、ここにここに置かれた左外部結合を受け入れないというエラーが出ます:

Msg 156, Level 15, State 1, Server TESTSERVER, Line 3
Incorrect syntax near the keyword 'LEFT'.
Msg 156, Level 15, State 1, Server TESTSERVER, Line 7
Incorrect syntax near the keyword 'SET'.
Msg 102, Level 15, State 1, Server TESTSERVER, Line 7
Incorrect syntax near '='.
Msg 102, Level 15, State 1, Server TESTSERVER, Line 15
Incorrect syntax near '='.
Msg 102, Level 15, State 1, Server TESTSERVER, Line 16
Incorrect syntax near '='.
Msg 102, Level 15, State 1, Server TESTSERVER, Line 17
Incorrect syntax near '='.
Msg 102, Level 15, State 1, Server TESTSERVER, Line 19
Incorrect syntax near '='.

私も次のように試しました:

UPDATE
    TESTDB
SET
    (SELECT UPPER(string19) FROM TESTDB.UDPERSONSMALL WHERE TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.UDPERSONSMALL_id) = 'X'
FROM
    TESTDB.CONTACT 
    LEFT OUTER JOIN TESTDB.PERSON ON TESTDB.CONTACT.contact_id = TESTDB.PERSON.contact_id
    LEFT OUTER JOIN TESTDB.UDPERSONSMALL ON TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.udpersonSmall_id 
    LEFT OUTER JOIN TESTDB.UDCONTACTLARGE ON TESTDB.CONTACT.userdef2_id = TESTDB.UDCONTACTLARGE.udcontactLarge_id
WHERE 
    (TESTDB.CONTACT.contact_id = TESTDB.PERSON.contact_id) 
/*  No retired people*/
    AND TESTDB.PERSON.retired = '0'
/*  Other conditions*/
    AND ((SELECT UPPER(string05) FROM TESTDB.UDPERSONSMALL WHERE TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.UDPERSONSMALL_id) = 'X'
    OR  (SELECT UPPER(string07) FROM TESTDB.UDPERSONSMALL WHERE TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.UDPERSONSMALL_id) = 'X'
    OR  (SELECT UPPER(string08) FROM TESTDB.UDPERSONSMALL WHERE TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.UDPERSONSMALL_id) = 'X')
/*  testpersonen*/
    AND (SELECT string45 FROM TESTDB.UDPERSONLARGE WHERE TESTDB.PERSON.userdef2_id = TESTDB.UDPERSONLARGE.UDPERSONLARGE_id) = '123'

これにより、別のエラーが発生します。

Msg 102, Level 15, State 1, Server TESTSERVER, Line 4
Incorrect syntax near '('.
Msg 102, Level 15, State 1, Server TESTSERVER, Line 4
Incorrect syntax near '='.
Msg 102, Level 15, State 1, Server TESTSERVER, Line 17
Incorrect syntax near '='.
Msg 102, Level 15, State 1, Server TESTSERVER, Line 18
Incorrect syntax near '='.
Msg 102, Level 15, State 1, Server TESTSERVER, Line 19
Incorrect syntax near '='.
Msg 102, Level 15, State 1, Server TESTSERVER, Line 21
Incorrect syntax near '='.

ソフトウェアは、SQL Server 2005データベースを備えたCRMです。

誰かが構文を教えてくれませんか?私は道に迷っています。

前もって感謝します。

1
WickedNet

SELECTクエリはかなり簡略化できるため、必要なUPDATEステートメントを簡単に把握できます。それらすべてSELECT UPPERはすでに結合しているため不要です。列を参照してください。

テスト環境でこれを試してください:

UPDATE c
SET TestField = UPPER(udps.string19)
FROM         
    TESTDB.CONTACT c
    LEFT OUTER JOIN TESTDB.PERSON p ON c.contact_id = p.contact_id
    LEFT OUTER JOIN TESTDB.UDPERSONSMALL udps ON p.userdef_id = udps.udpersonSmall_id 
    LEFT OUTER JOIN TESTDB.UDCONTACTLARGE udc ON c.userdef2_id = udc.udcontactLarge_id
    LEFT OUTER JOIN TESTDB.UDPERSONLARGE udpl ON p.userdef2_id = udpl.UDPERSONLARGE_id
WHERE 
/*  No retired people*/
    p.retired = '0'
/*  Other conditions*/
    AND (UPPER(udps.string05) = 'A'
    OR   UPPER(udps.string07) = 'B'
    OR   UPPER(udps.string08) = 'C')
/*  testpersonen*/
    AND udpl.string45 = '123'
3
Tara Kizer

これが役立つかどうかを確認してください:

Update TESTDB.CONTACT 
SET Testfield = SubTestField
FROM
(
SELECT
    TESTDB.CONTACT.number2 AS CustomerID,
    TESTDB.PERSON.firstname AS FirstName,
    TESTDB.PERSON.lastname AS LastName,
    TESTDB.CONTACT.contact_id AS SubContact_ID
    (SELECT UPPER(string19) FROM TESTDB.UDPERSONSMALL WHERE TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.UDPERSONSMALL_id) AS SubTestfield
FROM         
    TESTDB.CONTACT 
    LEFT OUTER JOIN TESTDB.PERSON ON TESTDB.CONTACT.contact_id = TESTDB.PERSON.contact_id
    LEFT OUTER JOIN TESTDB.UDPERSONSMALL ON TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.udpersonSmall_id 
    LEFT OUTER JOIN TESTDB.UDCONTACTLARGE ON TESTDB.CONTACT.userdef2_id = TESTDB.UDCONTACTLARGE.udcontactLarge_id
WHERE 
    (TESTDB.CONTACT.contact_id = TESTDB.PERSON.contact_id) 
/*  No retired people*/
    AND TESTDB.PERSON.retired = '0'
/*  Other conditions*/
    AND (
    (SELECT UPPER(string05) FROM TESTDB.UDPERSONSMALL WHERE TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.UDPERSONSMALL_id) = 'A'
    OR  (SELECT UPPER(string07) FROM CRM5.UDPERSONSMALL WHERE TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.UDPERSONSMALL_id) = 'B'
    OR  (SELECT UPPER(string08) FROM CRM5.UDPERSONSMALL WHERE TESTDB.PERSON.userdef_id = TESTDB.UDPERSONSMALL.UDPERSONSMALL_id) = 'C'
    )
/*  testpersonen*/
    AND (SELECT string45 FROM TESTDB.UDPERSONLARGE WHERE TESTDB.PERSON.userdef2_id = TESTDB.UDPERSONLARGE.UDPERSONLARGE_id) = '123'
    )Sub
Where TESTDB.CONTACT.contact_id = SubContact_ID

セット句には、比較する値が必要です。別の例については、この answerRobin Day を参照してください。見やすくするために、以下の例も掲載します。

UPDATE
    Table_A
SET
    Table_A.col1 = Table_B.col1,
    Table_A.col2 = Table_B.col2
FROM
    Some_Table AS Table_A
    INNER JOIN Other_Table AS Table_B
        ON Table_A.id = Table_B.id
WHERE
    Table_A.col3 = 'cool'
2
Shaulinator