我无法从表格中选择所有行并使用0填充不匹配的行。
Table "modul" ---------------------------------------------------------- | id | menu_name | modul_name | all_access | ---------------------------------------------------------- 1 books book 0 2 cds cd 0 3 tapes tape 0
table "user" -------------------- | id | username | -------------------- 1 vedran
table "user_modul" ------------------------------------------ | id | user_id | modul_id | active | ------------------------------------------ 1 1 1 1 2 1 2 1 3 2 2 1
如果我运行用户名" vedran"的查询我想得到像这样的输出
------------------------------------------------------------------ | id | menu_name | modul_name | all_access | active | ------------------------------------------------------------------ 1 books book 0 1 2 cds cd 0 1 3 tapes tape 0 0
因此用户vedran的id为1,id为1的用户有活动的模块1和2,但我也想获得第三个模块,但设置为0。
模型看起来像这样:
我尝试使用此查询:
SELECT M.*, ZM.active FROM modul M JOIN user_modul UM ON (M.id = UM.modul_id) JOIN user U ON (UM.user_id = U.id) WHERE U.id = 1 ORDER BY M.id ASC
但这只返回两行而不是" modul"的所有行。表
答案 0 :(得分:2)
http://sqlfiddle.com/#!2/30f01/1
SELECT
m.* , COALESCE(um.active,0)
FROM user u
RIGHT JOIN modul m
ON 1
LEFT JOIN user_modul um
ON um.modul_id = m.id AND um.user_id=u.id
WHERE u.username='vedran'
编辑1 CROSS JOIN经典解决方案,没有棘手ON 1
http://sqlfiddle.com/#!2/30f01/2
SELECT
m.* , COALESCE(um.active,0)
FROM user u
CROSS JOIN modul m
LEFT JOIN user_modul um
ON um.modul_id = m.id AND um.user_id=u.id
WHERE u.username='vedran';
答案 1 :(得分:0)
也许您可以使用UNION
和NOT IN
执行此类操作:
SELECT modul.id AS id, modul.menu_name AS menu_name, modul.modul_name AS modul_name, modul.all_access AS all_access, "1" AS active
FROM modul
LEFT JOIN user_modul
ON user_modul.modul_id = modul.id
LEFT JOIN user
ON user.id = user_modul.user_id
WHERE user.username = "vedran"
UNION
SELECT id, menu_name, modul_name, all_access, "0" AS active
FROM modul
WHERE id NOT IN
SELECT modul.id
FROM modul
LEFT JOIN user_modul
ON user_modul.modul_id = modul.id
LEFT JOIN user
ON user.id = user_modul.user_id
WHERE user.username = "vedran"
基本上,我正在做的事情,在获取用户可以访问的所有模块,并在1
列中添加active
的值,然后,我添加到此列出用户无法访问的所有模块,其值为0
。
也许这段代码包含一些错误,因为我没有尝试过(我没有数据库来测试它),但我认为你得到了它。
我希望我帮助你完成你的项目。
编辑:也许您可以使用temporary table
来避免重复查询
答案 2 :(得分:0)
如果您想要modul
表中的所有行,我的建议是先放置该表,然后将left join
用于其余表:
SELECT M.*, COALESCE(UM.active, 0)
FROM modul M LEFT JOIN
user_modul UM
ON M.id = UM.modul_id LEFT JOIN
user U
ON UM.user_id = U.id AND U.id = 1
ORDER BY M.id ASC
将WHERE
逻辑移到ON
子句非常重要。
我不建议在同一查询中混合使用left join
和right join
。关于哪个表保留所有行,会让人感到困惑。