扩展结果集,添加从另一个表的不同行中获取的列

时间:2014-11-25 14:27:24

标签: mysql sql

美好的一天!

我们说我有两个表定义如下:

TABLE USER(id,name,...其他不重要的字段)

| id | name |
-------------
|  1 | John | 
|  2 | Mary | 
|  3 | Luke |
|  4 | Lisa |

TABLE CHOICE(id,uid,kname)其中uid是表USER的外键。

请注意:我不知道表CHOICE有多少不同的kname条目。我唯一知道的是它们会受到限制(比如0到10之间)。

| id | uid |  kname |
---------------------
|  1 |  1  |  city1 |
|  2 |  1  |  city2 |
|  4 |  2  |  city2 |
|  5 |  2  |  city3 |
|  6 |  4  |  city4 |

是否可以编写一个返回该表的查询:

| id | name | city1 | city2 | city3 | city4 |
---------------------------------------------
|  1 | John |   1   |   1   |   0   |   0   |
|  2 | Mary |   0   |   1   |   1   |   0   |
|  3 | Luke |   0   |   0   |   0   |   0   |
|  4 | Lisa |   0   |   0   |   0   |   1   |

我。即表格USER扩展了表CHOICE中的不同kname,标有kname,如果在CHOICE中存在一行,其中uid等于用户id,则为1,否则为零。

2 个答案:

答案 0 :(得分:0)

这样的东西
SELECT u.id, u.name, (SELECT COUNT(c.uid) FROM CHOICE WHERE c.kname = 'city1') AS city1, (SELECT COUNT(c.uid) FROM CHOICE WHERE c.kname = 'city2') AS city2, (SELECT COUNT(c.uid) FROM CHOICE WHERE c.kname = 'city3') AS city4, (SELECT COUNT(c.uid) FROM CHOICE WHERE c.kname = 'city4') AS city4
FROM USER u 
INNER JOIN CHOICE c ON u.id = c.uid
GROUP BY u.id, u.name

答案 1 :(得分:0)

不需要子查询。通常你会这样做

sum(kname = 'city1') as city1

,因为kname = 'city1'等于true或false,1或0.但是你必须处理可能的null值,因为你必须离开join来获取users表中的所有条目,甚至是表choice中没有相应条目的那些。因此使用coalesce()函数(它返回其第一个参数,不是null)。

select 
u.id, 
u.name, 
sum(coalesce(kname, '') = 'city1') as city1, 
sum(coalesce(kname, '') = 'city2') as city2, 
sum(coalesce(kname, '') = 'city3') as city3, 
sum(coalesce(kname, '') = 'city4') as city4 
from user u 
left join choice c on c.uid = u.id 
group by u.id, u.name;

+------+------+-------+-------+-------+-------+
| id   | name | city1 | city2 | city3 | city4 |
+------+------+-------+-------+-------+-------+
|    1 | John |     1 |     1 |     0 |     0 |
|    2 | Mary |     0 |     1 |     1 |     0 |
|    3 | Luke |     0 |     0 |     0 |     0 |
|    4 | Lisa |     0 |     0 |     0 |     1 |
+------+------+-------+-------+-------+-------+