MySQL:使用条件连接改进查询

时间:2017-02-07 08:53:52

标签: mysql sql join

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,使用连接缓冲区(flat,BNL join),使用连接缓冲区(incremental,BNL join)。这看起来不太好。

此外,LEFT Joins应该是INNER,但是在内部它不显示任何结果......(和相同的temporarys,filesorts,缓冲区等)

我尝试了不同的语法(可能是错的),结果相同:

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

我可以做两个查询,但我试图在一个查询中执行:)

3 个答案:

答案 0 :(得分: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是正确的方法,因为通知来自用户或博客,而不是两者。

答案 1 :(得分:0)

尝试以下查询:

这使用内连接和直接连接条件。 请注意,SELECT子句中有一个额外的列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;

答案 2 :(得分: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