GROUP_CONCAT的替代方案?多个连接到同一个表,不同的列

时间:2014-01-17 20:41:52

标签: mysql sql

我甚至不确定这里的正确术语。 MySQL新手,或多或少。

给定几个表定义如下:

    CREATE TABLE users 
 ( user_id int(11) NOT NULL auto_increment
 , name VARCHAR(255)
 , pri_location_id mediumint(8)
 , sec_location_id mediumint(8)
 , PRIMARY KEY  (user_id)
 );

 CREATE TABLE locations 
 ( location_id mediumint(8) NOT NULL AUTO_INCREMENT
 , name varchar(255)
 , PRIMARY KEY (location_id)
 )

我正在尝试进行查询以一次性获取用户名以及主要和辅助位置。

我可以得到这样的一个:

SELECT u.name AS user_name, l.name as primary_location FROM users u, locations l WHERE u.primary_location_id=l.location_id

但是我在一个查询中使用正确的语法总是空白。

2 个答案:

答案 0 :(得分:2)

SELECT u.name AS user_name, l1.name as primary_location , l2.name as secondary_location
FROM users u
JOIN locations l1 ON(u.pri_location_id=l1.location_id)
JOIN locations l2 ON(u.sec_location_id = l2.location_id);

答案 1 :(得分:-1)

首先,如果允许添加可用于正确描述这种多对多关系的users_locations表,我会强烈考虑更改数据库模式。

此表格如下:

user_id    location_id    location_type
1          1              primary
1          2              secondary
2          1              secondary
2          2              primary

等等。

您可能希望在所有三列中都使用复合主键。而location_type最好是枚举数据类型。

您的查询就像

SELECT
    u.name AS user_name
    l.name AS location_name
    ul.location_type AS location_type
FROM users AS u
INNER JOIN user_location AS ul /* possibly use left join here if user can exist without a location */
  ON u.user_id = ul.user_id
INNER JOIN locations AS l
  ON ul.location_id = l.location_id
ORDER BY ul.location_type ASC

这将为每个用户返回最多两条记录(主要和次要的单独记录,首先列出的主要记录)

如果您需要将此折叠为单个记录,则可以执行此操作:

SELECT
    u.name AS user_name
    COALESCE(CASE WHEN ul.location_type = 'primary' THEN l.name ELSE NULL END CASE) AS primary_location,
    COALESCE(CASE WHEN ul.location_type = 'secondary' THEN l.name ELSE NULL END CASE) AS secondary_location
FROM users AS u
INNER JOIN user_location AS ul /* possibly use left join here if user can exist without a location */
  ON u.user_id = ul.user_id
INNER JOIN locations AS l
  ON ul.location_id = l.location_id
GROUP BY `user_name`

如果您仍然坚持使用当前架构,那么@Jlil的解决方案应该适合您。