2017-02-07 7 views
0
SELECT n.type, n.type_id, n.data, 
(CASE WHEN (n.type='users') THEN users.u_name ELSE NULL END) AS user_name, 
(CASE WHEN (n.type='blogs') THEN blogs.b_name ELSE NULL END) AS blog_name 
FROM notifications AS n 
LEFT JOIN users ON (CASE 
        WHEN (n.type='users') AND n.type_id=users.id THEN 1 
        ELSE 0 
        END = 1) 
LEFT JOIN blogs ON (CASE 
        WHEN (n.type='blogs') AND n.type_id=blogs.id THEN 1 
        ELSE 0 
        END = 1) 
WHERE n.receiver_id = 1 
ORDER BY n.id DESC LIMIT 20 

これは機能しますが、使用します。 filesortの使用、結合バッファーの使用(フラット、BNL結合)、結合バッファーの使用(増分、BNL結合)。それは良く見えません。MySQL:条件付き結合によるクエリの改善

さらにより、LEFTはINNERでなければなりませんが、内部でそれがどんな結果が表示されない...(と同じtemporarys、filesorts、バッファなど)参加

私は別の構文が(おそらく間違っtryied )同じ結果を:

(CASE WHEN (n.type='blogs') THEN n.type_id=blogs.id ELSE NULL END) 

私は2つのクエリを行うことができますが、私は1つでそれをやろうとしている:)

答えて

3
SELECT n.type, n.type_id, n.data, 
     users.u_name as user_name, 
     blogs.b_name AS blog_name 
FROM notifications AS n 
LEFT JOIN users ON n.type='users' AND n.type_id=users.id 
LEFT JOIN blogs ON n.type='blogs' AND n.type_id=blogs.id 
WHERE n.receiver_id = 1 
ORDER BY n.id DESC 
LIMIT 20 

あなたはケースを必要としません。通知はユーザーまたはブログからのものであり、両方からのものではないため、left joinは適切なアプローチです。クエリ以下

+0

は、それは私に何の結果が得られていないと "エクストラ:インポッシブルWHERE" と他のすべてがNULLのフィールドを説明します。 – Vixxs

+0

それは本当に奇妙です。あなたの質問にサンプルデータと予想される結果を加えてください。 –

+0

n.typeはユーザーまたはブログと異なる場合があります。ユーザーまたはブログの名前を必要としない操作からのものでもかまいません。 – Vixxs

0

試してみてください。

これは内部結合とまっすぐ結合条件を使用しています。 SELECT句に1つの余分な列n.idがあります。

SELECT n.id, n.type, n.type_id, n.data, u.u_name AS user_name, NULL AS blog_name 
FROM notification n INNER JOIN users u ON n.receiver_id = 1 AND n.type = 'users' AND n.type_id = u.id 
UNION ALL 
SELECT n.id, n.type, n.type_id, n.data, NULL AS user_name, b.b_name AS blog_name 
FROM notification n INNER JOIN blogs b ON n.receiver_id = 1 AND n.type = 'blogs' AND n.type_id = b.id 
ORDER BY 1 DESC LIMIT 20; 
0

これを試してみてください:

SELECT n.type, n.type_id, n.data, 
    (select u.u_name from users as u where u.id = n.type_id and n.type = 'users'), 
    (select b.b_name from blogs as b where b.id = n.type_id and n.type = 'blogs') 
FROM notifications AS n 
WHERE n.receiver_id = 1 
ORDER BY n.id DESC LIMIT 20 
関連する問題