0

誰かが別のテーブルに何かを既に入力しているかどうかを確認するクエリがあります。最初にテーブルにあるかどうかをチェックし、次にUNIONの後にテーブルにないかどうかをチェックします..

私は、私よりも SQL についてよく知っている人と一緒に、このクエリを作成しました。今思うのは、これを短縮できるかどうかです。

2つのクエリでチェックしてユニオンを実行する代わりに、CASE WHEN .. THEN 0 ELSE 1で多分考えていました

SELECT
        l.id, 
        l.naam, 
        r.id as revisie, 
        r.beschrijving as revisiebeschrijving,
        "DONE"
    FROM lijsten l
    JOIN revisies r ON r.lijst_id = l.id
    JOIN werknemerlijsten wl ON wl.lijst_id = l.id
    WHERE
        wl.werknemer_id = :id AND r.actief = 1
        AND r.id IN 
        (
            SELECT
                    r2.id
                FROM revisies r2
                JOIN antwoorden a ON a.revisie_id = r2.id
                WHERE a.werknemer_id = wl.werknemer_id
        )
UNION
SELECT
        l.id, 
        l.naam, 
        r.id as revisie, 
        r.beschrijving as revisiebeschrijving,
        "NOT DONE"
    FROM lijsten l
    JOIN revisies r ON r.lijst_id = l.id
    JOIN werknemerlijsten wl ON wl.lijst_id = l.id
    WHERE
        wl.werknemer_id = :id AND r.actief = 1
        AND r.id NOT IN 
        (
            SELECT
                    r2.id
                FROM revisies r2
                JOIN antwoorden a ON a.revisie_id = r2.id
                WHERE a.werknemer_id = wl.werknemer_id
        )

最終的解決

これが最終的な解決策です。このバージョンでは、サブクエリなしで ORDER BY が機能します。

SELECT l.id
 , l.naam
 , r.id as revisie
 , r.beschrijving as revisiebeschrijving
 , CASE WHEN a.werknemer_id IS NULL
        THEN 0
        ELSE 1 END AS ingevuld
FROM werknemerlijsten AS wl 
INNER  
JOIN lijsten AS l
ON l.id =  wl.lijst_id 
INNER
JOIN revisies AS r 
ON r.lijst_id = l.id
AND r.actief = 1
LEFT OUTER
JOIN antwoorden AS a 
 ON a.revisie_id = r.id
AND a.werknemer_id = wl.werknemer_id
WHERE wl.werknemer_id = :id
ORDER BY ingevuld
4

2 に答える 2

1

あなたの推測は正しいです。これは を使用して短縮できますCASE WHEN...END。このようにして、 を短縮し、WHEREを取り除くUNION SELECTこともできます。これにより、速度が向上する可能性もあります。簡単に書き直すと、次のようになります。

SELECT
        l.id, 
        l.naam, 
        r.id as revisie, 
        r.beschrijving as revisiebeschrijving,
        CASE WHEN
            (
                SELECT
                    r2.id
                FROM revisies r2
                JOIN antwoorden a ON a.revisie_id = r2.id
                WHERE
                    a.werknemer_id = wl.werknemer_id
                    AND r2.id = r.id
            ) IS NOT NULL THEN
            "DONE"
        ELSE
            "NOT DONE"
        END
    FROM lijsten l
    JOIN revisies r ON r.lijst_id = l.id
    JOIN werknemerlijsten wl ON wl.lijst_id = l.id
    WHERE
        wl.werknemer_id = :id AND r.actief = 1

コメントで述べたように、LEFT JOINここでも a は問題ないので、ここのサブセレクトはa ...CASEに移動しますLEFT JOIN

于 2013-09-25T09:15:07.753 に答える