我有一个供用户使用的表格:
USERS:
ID | NAME |
----------------
1 | JOHN |
2 | STEVE |
计算机表:
COMPUTERS:
ID | USER_ID |
------------------
13 | 1 |
14 | 1 |
处理器表:
PROCESSORS:
ID | NAME |
---------------------------
27 | PROCESSOR TYPE 1 |
28 | PROCESSOR TYPE 2 |
和硬盘表:
HARDDRIVES:
ID | NAME |
---------------------------|
35 | HARDDRIVE TYPE 25 |
36 | HARDDRIVE TYPE 90 |
每台计算机可以有不同属性表(处理器,硬盘等)的许多属性,所以我有这样的交集表,将属性链接到计算机:
COMPUTER_PROCESSORS:
C_ID | P_ID |
--------------|
13 | 27 |
13 | 28 |
14 | 27 |
COMPUTER_HARDDRIVES:
C_ID | H_ID |
--------------|
13 | 35 |
因此,具有id 1的用户JOHN拥有计算机13和14.计算机13具有处理器27和28,并且计算机13具有硬驱动器35.计算机14具有处理器27并且没有硬盘驱动器。
鉴于用户的ID,我想检索该用户计算机的每个计算机属性的列表。
我找到了一个给我一些结果的查询:
SELECT computers.id, processors.id AS p_id, processors.name AS p_name, harddrives.id AS h_id, harddrives.name AS h_name,
FROM computers
JOIN computer_processors ON (computer_processors.c_id = computers.id)
JOIN processors ON (processors.id = computer_processors.p_id)
JOIN computer_harddrives ON (computer_harddrives.c_id = computers.id)
JOIN harddrives ON (harddrives.id = computer_harddrives.h_id)
WHERE computers.user_id = 1
结果:
ID | P_ID | P_NAME | H_ID | H_NAME |
-----------------------------------------------------------
13 | 27 | PROCESSOR TYPE 1 | 35 | HARDDRIVE TYPE 25 |
13 | 28 | PROCESSOR TYPE 2 | 35 | HARDDRIVE TYPE 25 |
但这有几个问题......
计算机14没有出现,因为它没有硬盘。 我可以以某种方式进行外部联接以确保所有计算机都显示出来,即使它们没有某些属性吗?
计算机13出现两次,两者都有相同的硬盘监听。当更多属性被添加到计算机(例如3块ram)时,为该计算机返回的行数变得非常大,并且它必须在应用程序代码中对结果进行排序。 我可以以某种方式进行查询,将两个返回的行组合在一起吗?或者在第二行的h_name列中返回NULL的查询,以便返回的所有值都是唯一的?
编辑: 我想要回归的是:
ID | P_ID | P_NAME | H_ID | H_NAME |
-----------------------------------------------------------
13 | 27 | PROCESSOR TYPE 1 | 35 | HARDDRIVE TYPE 25 |
13 | 28 | PROCESSOR TYPE 2 | 35 | NULL |
14 | 27 | PROCESSOR TYPE 1 | NULL | NULL |
或者任何可以轻松将其变成像这样的数组的结果
[13] =>
[P_NAME] =>
[0] => PROCESSOR TYPE 1
[1] => PROCESSOR TYPE 2
[H_NAME] =>
[0] => HARDDRIVE TYPE 25
[14] =>
[P_NAME] =>
[0] => PROCESSOR TYPE 1
答案 0 :(得分:4)
使用LEFT JOIN
代替INNER JOIN
。这两个连接彼此不同。 INNER JOIN
(您当前使用的 )仅返回表格两侧至少有一个匹配的记录。这就是为什么computer 14
不应该因为它在表COMPUTER_HARDDRIVES
上没有匹配的原因。另一方面,LEFT JOIN
返回左侧表中的所有记录,无论表格的另一侧是否匹配。
SELECT a.ID AS UserID,
a.Name as UserName,
b.ID as ComputerID,
d.ID as ProcessorID,
d.Name as ProcessorName,
f.ID as HardDriveID,
f.name as HardDriveName
FROM users a
INNER JOIN computers b
ON a.ID = b.user_ID
LEFT JOIN computer_processors c
ON b.ID = c.C_ID
LEFT JOIN PROCESSORS d
ON c.p_ID = d.ID
LEFT JOIN COMPUTER_HARDDRIVES e
ON b.ID = e.c_ID
LEFT JOIN HARDDRIVE f
ON e.h_ID = f.ID
WHERE a.ID = 1
由于您希望将行组合在一起,因此您可以利用GROUP_CONCAT()
函数。基本上,它的作用是将列的值组合成逗号分隔值
SELECT a.ID AS UserID,
a.Name as UserName,
b.ID as ComputerID,
GROUP_CONCAT(DISTINCT d.ID) as ProcessorID,
GROUP_CONCAT(DISTINCT d.Name) as ProcessorName,
GROUP_CONCAT(DISTINCT f.ID) as HardDriveID,
GROUP_CONCAT(DISTINCT f.name) as HardDriveName
FROM users a
INNER JOIN computers b
ON a.ID = b.user_ID
LEFT JOIN computer_processors c
ON b.ID = c.C_ID
LEFT JOIN PROCESSORS d
ON c.p_ID = d.ID
LEFT JOIN COMPUTER_HARDDRIVES e
ON b.ID = e.c_ID
LEFT JOIN HARDDRIVE f
ON e.h_ID = f.ID
WHERE a.ID = 1
GROUP BY UserID, UserName, ComputerID
答案 1 :(得分:3)
尝试:
SELECT computers.id,
group_concat(distinct processors.id) AS p_ids,
group_concat(distinct processors.name) AS p_names,
group_concat(distinct harddrives.id) AS h_ids,
group_concat(distinct harddrives.name) AS h_names
FROM computers
JOIN computer_processors ON (computer_processors.c_id = computers.id)
JOIN processors ON (processors.id = computer_processors.p_id)
LEFT JOIN computer_harddrives ON (computer_harddrives.c_id = computers.id)
LEFT JOIN harddrives ON (harddrives.id = computer_harddrives.h_id)
WHERE computers.user_id = 1
group by computers.id
答案 2 :(得分:1)
SELECT computers.id, processors.id AS p_id, processors.name AS p_name, harddrives.id AS h_id, harddrives.name AS h_name
FROM computers
LEFT JOIN computer_processors ON (computer_processors.c_id = computers.id)
LEFT JOIN processors ON (processors.id = computer_processors.p_id)
LEFT JOIN computer_harddrives ON (computer_harddrives.c_id = computers.id)
LEFT JOIN harddrives ON (harddrives.id = computer_harddrives.h_id)
WHERE computers.user_id = 1
答案 3 :(得分:0)
select u.ID user_id,
u.name user_name
p.id,
p.name,
h.id,
h.name
from USERS u join COMPUTERS c
on u.id=c.USER_ID
join PROCESSORS p
on c.id=p.id
join HARDDRIVES h
on c.id=h.id
where u.id=1