繁体   English   中英

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

[英]Selecting multiple values from same column with a single Select query

因此,我有两个表:用户和任务;

用户:

 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

我想做的是用users表中的first_name + last_name替换assigned_user_id creator_idcreator_id 所以我执行以下查询:

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 ,而我在哪里做错了? 提前致谢!

您需要两次连接到用户表并对它们进行别名...

像...

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

由于您有两个外键,并且要获取对应的数据,因此只需INNER JOIN users表两次即可。

您使用了LEFT JOIN,它将在您的tasks从第一个表中获取所有数据,即使在第二个表中未找到匹配项(在您的情况下,这没有什么区别,但是在未设置id的情况下,用户不再存在,也许这是一个问题,由您决定...),并且您还在JOIN条件中使用了OR ,这导致结果中出现重复的任务。

因此,您必须两次INNER JOIN。一次获取分配的用户,一次获取创建者。

Havent经过测试,但这应该可以:

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

我在SQL Server上对此进行了测试,并重现了与您相同的问题,希望对您有所帮助。

当我进行测试时,两个SELECT CONCAT语句两次都使用相同的user_id。 因此,问题似乎是不是一次检查两个ID,而是一次检查两个ID。 因此,如果我要使用您的示例,它首先在两个SELECT CONCAT语句中都使用Petyo的ID(仅填充creator_user角色,因此另一个变为false),然后在两个SELECT CONCAT语句中都使用Gosho的ID,也仅填充一个字段( assigned_user字段),另一字段为null。

因此,您需要做的是再次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

谢谢大家,但我通过以下方法解决了问题:

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

我只是在每个内部SELECT添加了FROM UsersWHERE子句,所以我不必进行任何连接……一如既往,它比我想象的要简单得多。 再次感谢,非常感谢!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM