简化SQL UNION查询

时间:2014-06-08 00:14:39

标签: sql left-join union

我实际上有三张桌子。它们是类别,用户和用户类别。如您所见,可以通过m-n userCategories表将用户分配到多个类别。

我想为特定用户选择所有类别。如果将类别分配给该给定用户,则userFk-column应为userId(例如5),否则为NULL。

我的查询得到了类似的结果。但有没有办法简化这个查询?

select * 
from (
  SELECT `categoryId`, `category`, userFk FROM `category` c
  left join usercategories uc on c.categoryId = uc.catFk
  where userFk = 5
 union
  SELECT `categoryId`, `category`, userFk FROM `category` c
  left join usercategories uc on c.categoryId = uc.catFk
  where userFk != 5 OR userFk is NULL
) as result
group by categoryId

3 个答案:

答案 0 :(得分:2)

如果将userid放在左连接子句中,它将为你保存联合

SELECT `categoryId`, `category`, userFk 
FROM `category` c
LEFT JOIN usercategories uc on c.categoryId = uc.catFk AND userFk = 5

这样,查询的唯一可能结果是userFK=5NULL,从而也为您节省了WHERE子句。

由于您的用户所拥有的类别只能在userFK = NULL元组中显示一次,因此您也不需要group by,除非有一些重复,我没有看到。

答案 1 :(得分:0)

如果您想要使用的用户类别:

SELECT `categoryId`, `category`, userFk FROM `category` c
left join usercategories uc on c.categoryId = uc.catFk
where userFk = 5 

我认为userCategories没有空值,没有类别的用户不应该在userCategories表中。

答案 2 :(得分:0)

在子查询中,union的两个部分除了where子句之外是相同的。子查询的所有记录都将属于这两个条件中的任何一个,因此不是

SELECT `categoryId`, `category`, userFk FROM `category` c
left join usercategories uc on c.categoryId = uc.catFk
where userFk = 5
union
SELECT `categoryId`, `category`, userFk FROM `category` c
left join usercategories uc on c.categoryId = uc.catFk
where userFk != 5 OR userFk is NULL

等同于

SELECT `categoryId`, `category`, userFk FROM `category` c
left join usercategories uc on c.categoryId = uc.catFk

我错过了什么吗?