我有两个实体,“用户”和“产品”,以及两个表:一个存储哪些用户查看了哪些产品,另一个存储哪些用户喜欢哪些产品。我想查询一次并返回结果,如下图所示:
表“视图”:
表“喜欢”:
查询结果:
理想情况下,结果中不应有重复的 user_id、product_id。请注意,如果用户既没有查看也没有喜欢产品,则不应返回该产品(即,不应有 FALSE、FALSE 行)。
由于 MySQL 不支持 FULL JOIN,我怀疑应该有一个使用 UNION ALL 的解决方法。我很欣赏任何想法。
你可以试试这个:
SELECT user_id, product_id, max(`view`) `view`, max(`like`) `like` FROM (
SELECT user_id, product_id, TRUE `view`, FALSE `like` FROM views
UNION ALL
SELECT user_id, product_id, FALSE, TRUE FROM likes
) s
GROUP BY user_id, product_id
顺便说一句,您应该尽量避免使用view
和like
作为名称,因为它们是 MySQL 中的保留字。
请记住,在 MySQL中true
,1
以及false
和0
是同义词。
在这里拉小提琴。
SELECT
v.User_ID, v.Product_ID, true AS `View`, IF (l.User_ID, true, false) AS `Like`
FROM views v
LEFT JOIN likes l ON (l.User_ID = v.User_ID AND l.Product_ID = v.Product_ID)
UNION
SELECT
l.User_ID, l.Product_ID, IF (v.User_ID, true, false) AS `View`, true AS `Like`
FROM likes l
LEFT JOIN views v ON (l.User_ID = v.User_ID AND l.Product_ID = v.Product_ID)
ORDER BY User_ID, Product_ID
另一种方法:
SELECT user_id, product_id,
'TRUE' AS view_result,
CASE WHEN l.user_id IS NULL THEN 'FALSE' ELSE 'TRUE' END AS like_result
FROM views AS v
NATURAL LEFT JOIN likes AS l
UNION ALL
SELECT user_id, product_id,
'FALSE', 'TRUE'
FROM views AS v
NATURAL RIGHT JOIN likes AS l
WHERE v.user_id IS NULL ;
测试:SQL-Fiddle
SELECT
User_ID,
Product_ID,
Views.User_ID IS NOT NULL AS View,
Likes.User_ID IS NOT NULL AS Like
FROM
Users
LEFT JOIN Views USING (User_ID)
LEFT JOIN Likes USING (User_ID)
WHERE
Views.User_ID IS NOT NULL
OR Likes.User_ID IS NOT NULL