使用单个Select查询从同一列中选择多个值

时间:2016-07-28 13:32:36

标签: mysql sql phpmyadmin statements

所以,我有两个表:用户和任务;

用户:

 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_idcreator_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_usercreator_user填充的情况下返回单行,我在哪里做错了?提前谢谢!

4 个答案:

答案 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添加了WHERESELECT个子句, 所以我没有做任何加入......一如既往,这比我想象的要简单得多。再次感谢,非常感谢!