如何进行 LEFT JOIN,但行与其在 MySQL 中的关系分开?
How can I make a LEFT JOIN, but with rows separed from its relations in MySQL?
我需要获取 table A 中的所有行,但要加入 table B(基本上是 LEFT JOIN
),而且,我需要获取 A table 行本身,例如,使用这些 tables :
Table答:
id
姓名
1
随机名称
2
随机名称#2
Table乙:
id
parent_id
位置
1
2
位置 #1
2
2
地点 #2
使用此查询:
SELECT * FROM A
LEFT JOIN B
ON A.id = B.parent_id;
我得到这样的结果:
id
姓名
id
parent_id
位置
1
随机名称
空
空
空
2
随机名称#2
1
2
位置 #1
2
随机名称#2
2
2
地点 #2
但我想得到这样的东西:
id
姓名
id
parent_id
位置
1
随机名称
空
空
空
2
随机名称#2
空
空
空
2
随机名称#2
1
2
位置 #1
2
随机名称#2
2
2
地点#2
如您所见,“随机名称#2”本身有一行与其连接分开,我该怎么做?
大意是有一个ads
table(table一个),而且,还有一个subads
table( table B) 与 ads
table 略有不同,我需要在唯一查询中显示所有广告和子广告。
坦克很多!
可能不是最好的实现,但直到有人想出合适的解决方案...
SELECT A.id, name, B.id, parent_id, location FROM A
LEFT JOIN B
ON A.id = B.parent_id;
UNION ALL
SELECT A.id, name, NULL as id, NULL as parent_id, NULL as location FROM A
WHERE A.id IN (SELECT parent_id FROM B)
只需 UNION ALL
另一个查询从 A 中获取与 B 匹配的值,因此第一个查询中没有 NULL 值。
两条建议:
SELECT * FROM A
INNER JOIN B
ON A.id = B.parent_id
UNION ALL
SELECT *, NULL, NULL, NULL FROM A
或
SELECT A.*,B.*
FROM (SELECT 1 A_ONLY UNION ALL SELECT 0) A_ONLY
CROSS JOIN A
LEFT JOIN B
ON A.id = B.parent_id AND NOT A_ONLY
WHERE A_ONLY OR B.parent_id
后者是一种你可以用来模拟 WITH ROLLUP 的方法,当它是不允许的或者当你想要一些与它产生的略有不同的东西时(这里,避免总计记录和避免双重记录时没有B 行)。
您可以使用 table 进行 INNER JOIN 而不是 LEFT JOIN 和 UNION ALL 内容:
两个查询必须return相同的列数。
SELECT *, NULL, NULL, NULL
FROM A
UNION ALL
SELECT *
FROM A
INNER JOIN B ON A.id = B.parent_id;
您只需要从 A 和内部 JOIN 的其余部分添加的 NULL 行
CREATE TABLE A
(`id` int, `name` varchar(14))
;
INSERT INTO A
(`id`, `name`)
VALUES
(1, 'Random name'),
(2, 'Random name #2')
;
CREATE TABLE B
(`id` int, `parent_id` int, `location` varchar(11))
;
INSERT INTO B
(`id`, `parent_id`, `location`)
VALUES
(1, 2, 'Location #1'),
(2, 2, 'Location #2')
;
(SELECT A.id as a_id,A.name,B.* FROM A
INNER JOIN B
ON A.id = B.parent_id)
UNION
(SELECT A.*,NULL,NULL,NULL FROM A)
ORDER by a_id,id;
a_id | name | id | parent_id | location
---: | :------------- | ---: | --------: | :----------
1 | Random name | null | null | null
2 | Random name #2 | null | null | null
2 | Random name #2 | 1 | 2 | Location #1
2 | Random name #2 | 2 | 2 | Location #2
db<>fiddle here
我需要获取 table A 中的所有行,但要加入 table B(基本上是 LEFT JOIN
),而且,我需要获取 A table 行本身,例如,使用这些 tables :
Table答:
id | 姓名 |
---|---|
1 | 随机名称 |
2 | 随机名称#2 |
Table乙:
id | parent_id | 位置 |
---|---|---|
1 | 2 | 位置 #1 |
2 | 2 | 地点 #2 |
使用此查询:
SELECT * FROM A
LEFT JOIN B
ON A.id = B.parent_id;
我得到这样的结果:
id | 姓名 | id | parent_id | 位置 |
---|---|---|---|---|
1 | 随机名称 | 空 | 空 | 空 |
2 | 随机名称#2 | 1 | 2 | 位置 #1 |
2 | 随机名称#2 | 2 | 2 | 地点 #2 |
但我想得到这样的东西:
id | 姓名 | id | parent_id | 位置 |
---|---|---|---|---|
1 | 随机名称 | 空 | 空 | 空 |
2 | 随机名称#2 | 空 | 空 | 空 |
2 | 随机名称#2 | 1 | 2 | 位置 #1 |
2 | 随机名称#2 | 2 | 2 | 地点#2 |
如您所见,“随机名称#2”本身有一行与其连接分开,我该怎么做?
大意是有一个ads
table(table一个),而且,还有一个subads
table( table B) 与 ads
table 略有不同,我需要在唯一查询中显示所有广告和子广告。
坦克很多!
可能不是最好的实现,但直到有人想出合适的解决方案...
SELECT A.id, name, B.id, parent_id, location FROM A
LEFT JOIN B
ON A.id = B.parent_id;
UNION ALL
SELECT A.id, name, NULL as id, NULL as parent_id, NULL as location FROM A
WHERE A.id IN (SELECT parent_id FROM B)
只需 UNION ALL
另一个查询从 A 中获取与 B 匹配的值,因此第一个查询中没有 NULL 值。
两条建议:
SELECT * FROM A
INNER JOIN B
ON A.id = B.parent_id
UNION ALL
SELECT *, NULL, NULL, NULL FROM A
或
SELECT A.*,B.*
FROM (SELECT 1 A_ONLY UNION ALL SELECT 0) A_ONLY
CROSS JOIN A
LEFT JOIN B
ON A.id = B.parent_id AND NOT A_ONLY
WHERE A_ONLY OR B.parent_id
后者是一种你可以用来模拟 WITH ROLLUP 的方法,当它是不允许的或者当你想要一些与它产生的略有不同的东西时(这里,避免总计记录和避免双重记录时没有B 行)。
您可以使用 table 进行 INNER JOIN 而不是 LEFT JOIN 和 UNION ALL 内容:
两个查询必须return相同的列数。
SELECT *, NULL, NULL, NULL
FROM A
UNION ALL
SELECT *
FROM A
INNER JOIN B ON A.id = B.parent_id;
您只需要从 A 和内部 JOIN 的其余部分添加的 NULL 行
CREATE TABLE A (`id` int, `name` varchar(14)) ; INSERT INTO A (`id`, `name`) VALUES (1, 'Random name'), (2, 'Random name #2') ;
CREATE TABLE B (`id` int, `parent_id` int, `location` varchar(11)) ; INSERT INTO B (`id`, `parent_id`, `location`) VALUES (1, 2, 'Location #1'), (2, 2, 'Location #2') ;
(SELECT A.id as a_id,A.name,B.* FROM A INNER JOIN B ON A.id = B.parent_id) UNION (SELECT A.*,NULL,NULL,NULL FROM A) ORDER by a_id,id;
a_id | name | id | parent_id | location ---: | :------------- | ---: | --------: | :---------- 1 | Random name | null | null | null 2 | Random name #2 | null | null | null 2 | Random name #2 | 1 | 2 | Location #1 2 | Random name #2 | 2 | 2 | Location #2
db<>fiddle here