所以,我有两个表:用户和任务;
用户:
user_id username password first_name last_name isAdmin
任务:
task_id name description assessment assigned_user_id fk creator_id fk created_on last_modified status
我想要做的是将assigned_user_id
和creator_id
替换为来自users表的first_name
+ last_name
。所以我执行以下查询:
SELECT `task_id`, `description`,`assessment`,
(SELECT CONCAT(`first_name`, ' ',`last_name`) WHERE `Tasks`.`assigned_user_id` = `Users`.`user_id`) AS assigned_user,
(SELECT CONCAT(`first_name`, ' ',`last_name`) WHERE `Tasks`.`creator_id`=`Users`.`user_id`) AS creator_user,
`created_on`,`last_modified`,`status`
FROM `Tasks`
LEFT JOIN `Users`
ON Tasks.assigned_user_id = Users.user_id
OR Tasks.creator_id = Users.user_id
WHERE task_id=2
问题是它返回2行。一个是assigned_user_id null
,填充creator_id
,另一个是另一种方式:
task_id description assessment assigned_user creator_user created_on last_modified status
2 SHA SA PII LI 24 NULL Petyo Chuliuv 2016-07-22 2016-07-22 1
2 SHA SA PII LI 24 Gosho Toshov NULL 2016-07-22 2016-07-22 1
问题是:如何在assigned_user
和creator_user
填充的情况下返回单行,我在哪里做错了?提前谢谢!
答案 0 :(得分:1)
您需要两次加入您的用户表并为其添加别名......
有些人喜欢......SELECT `task_id`, `description`,`assessment`,
(SELECT CONCAT(`assignedUsers.first_name`, ' ',`assignedUsers.last_name`) AS assigned_user,
(SELECT CONCAT(`createdUsers.first_name`, ' ',`createdUsers.last_name`) AS creator_user,
`created_on`,`last_modified`,`status`
FROM `Tasks`
LEFT JOIN `Users` assignedUsers ON Tasks.assigned_user_id = assignedUsers .user_id
LEFT JOIN `Users` createdUsers ON Tasks.creator_id = createdUsers .user_id
WHERE task_id=2
答案 1 :(得分:1)
由于您有两个外键并且想要获取相应的数据,您只需要在内部加入users
表两次。
你使用LEFT JOIN来获取第一个表中的所有数据,在你的情况tasks
中,即使在第二个表中找不到匹配项(在你的情况下,这没有任何区别,但在案例中)如果没有设置id或者用户不再存在,可能这是一个由您自行决定的问题......)并且您还在JOIN条件中使用OR
导致结果中出现重复任务
所以你必须INNER JOIN两次。有一次获得指定的用户和一个获得创作者。
没有经过测试,但这应该有效:
SELECT t.`task_id`, t.`description`,t.`assessment`,
CONCAT(u1.`firstname`,' ',u1.`lastname`) as creator,
CONCAT(u2.`firstname`,' ',u2.`lastname`) as assigned_user,
t.`created_on`,t.`last_modified`,t.`status`
FROM `tasks` t
INNER JOIN `users` u1 ON t.creator_id=u1.id
INNER JOIN `users` u2 ON t.assigned_user_id=u2.id
WHERE t.`task_id`=2
答案 2 :(得分:1)
我在SQL Server上对此进行了测试并重现了与您相同的问题,希望我可以提供帮助。
当我进行测试时,两个SELECT CONCAT
语句两次都使用相同的user_id。所以问题似乎是它不会同时检查两个ID,而是在不同的时间检查两个ID。因此,如果我要使用您的示例,它首先在两个SELECT CONCAT
语句中使用Petyo的id(仅填充creator_user
角色,因此另一个变为false)然后它在两个语句中使用Gosho的id SELECT CONCAT
语句也只填充一个字段(assigned_user
字段)并使另一个字段为空。
所以你需要做的是再次JOIN
Users
表。一个用于指定,一个用于创建。像这样......
SELECT `task_id`, `description`,`assessment`,
(SELECT CONCAT(`U1.first_name`, ' ',`U1.last_name`)) AS assigned_user,
(SELECT CONCAT(`U2.first_name`, ' ',`U2.last_name`)) AS creator_user,
`created_on`,`last_modified`,`status`
FROM `Tasks`
LEFT JOIN `Users` U1
ON Tasks.assigned_user_id = U1.user_id
LEFT JOIN `Users` U2
ON Tasks.creator_id = U2.user_id
WHERE task_id=2
在你有OR
之前。它不会查看一方,查找id,然后查看另一方,查找id,然后立即使用它。就是这样。如果它正在查找的当前user_id
恰好是这两个中的一个,那么它会使用该单user_id
。
答案 3 :(得分:0)
谢谢所有人,但我通过以下方式解决了这个问题:
SELECT `task_id`, `description`,`assessment`,
(SELECT CONCAT(`first_name`, ' ', `last_name`)
FROM `Users`
WHERE `Tasks`.`assigned_user_id` = `Users`.`user_id`) AS assigned_user,
(SELECT CONCAT(`first_name`, ' ', `last_name`)
FROM `Users`
WHERE `Tasks`.`creator_id`=`Users`.`user_id`) AS creator_user,
`created_on`,`last_modified`,`status`
FROM `Tasks`
WHERE task_id=3
我刚在每个内部FROM Users
添加了WHERE
和SELECT
个子句,
所以我没有做任何加入......一如既往,这比我想象的要简单得多。再次感谢,非常感谢!