SQL - 根据分类值的存在插入常量
SQL - Insert constant based on the presence of categorical value
我在 MySQL 中有一个 table 如下所示:
ID
COMPONENT
AMOUNT
123
C1
12
123
C2
15.5
123
C3
13
234
C1
544
234
C2
546
445
C1
142
334
C1
13
并希望使用 SQL SELECT:
获得类似的东西
ID
COMPONENT
AMOUNT
123
C1
12
123
C2
15.5
123
C3
13
234
C1
544
234
C2
546
234
C3
0
445
C1
142
445
C2
0
445
C3
0
334
C1
13
334
C2
0
334
C3
0
意思是我想为给定 ID 不存在的组件显示 AMOUNT 0 的行。
这是一种方法:
select t1.id,
t1.component,
IFNULL(t2.amount,0) amount
from (
select a.id, b.component from table1 a
left join (select distinct component from table1) b on 1=1
group by a.id, b.component
) t1
left join table1 t2 on t1.id=t2.id and t1.component=t2.component
order by t1.id, t1.component;
解释: 第 1 步:子选择将 id 和组件的所有唯一组合放在一起,而不管数量值。第 2 步:进行左连接以计算每个 id/component 组合的金额。
如果您的 table 中没有 id/component 的重复组合,则此查询有效。如果每个组合确实有多个值,则可以在前两列上使用聚合函数,例如 group by
,在金额列上使用 sum()
。
结果:
id
component
amount
123
C1
12
123
C2
15.5
123
C3
13
234
C1
544
234
C2
546
234
C3
0
334
C1
13
334
C2
0
334
C3
0
445
C1
142
445
C2
0
445
C3
0
虚拟数据:
CREATE TABLE table1 (
id int(11),
component varchar(10),
amount float(5,1)
);
INSERT INTO table1 VALUES
(123, 'C1', 12),
(123, 'C2', 15.5),
(123, 'C3', 13),
(234, 'C1', 544),
(234, 'C2', 546),
(445, 'C1', 142),
(334, 'C1', 13);
您需要 CROSS
连接不同的 ID
到不同的 COMPONENT
和 LEFT
连接到 table:
SELECT i.ID, c.COMPONENT,
COALESCE(t.AMOUNT, 0) AMOUNT
FROM (SELECT DISTINCT ID FROM tablename) i
CROSS JOIN (SELECT DISTINCT COMPONENT FROM tablename) c
LEFT JOIN tablename t ON t.ID = i.ID AND t.COMPONENT = c.COMPONENT
ORDER BY i.ID, c.COMPONENT;
参见demo。
我在 MySQL 中有一个 table 如下所示:
ID | COMPONENT | AMOUNT |
---|---|---|
123 | C1 | 12 |
123 | C2 | 15.5 |
123 | C3 | 13 |
234 | C1 | 544 |
234 | C2 | 546 |
445 | C1 | 142 |
334 | C1 | 13 |
并希望使用 SQL SELECT:
获得类似的东西ID | COMPONENT | AMOUNT |
---|---|---|
123 | C1 | 12 |
123 | C2 | 15.5 |
123 | C3 | 13 |
234 | C1 | 544 |
234 | C2 | 546 |
234 | C3 | 0 |
445 | C1 | 142 |
445 | C2 | 0 |
445 | C3 | 0 |
334 | C1 | 13 |
334 | C2 | 0 |
334 | C3 | 0 |
意思是我想为给定 ID 不存在的组件显示 AMOUNT 0 的行。
这是一种方法:
select t1.id,
t1.component,
IFNULL(t2.amount,0) amount
from (
select a.id, b.component from table1 a
left join (select distinct component from table1) b on 1=1
group by a.id, b.component
) t1
left join table1 t2 on t1.id=t2.id and t1.component=t2.component
order by t1.id, t1.component;
解释: 第 1 步:子选择将 id 和组件的所有唯一组合放在一起,而不管数量值。第 2 步:进行左连接以计算每个 id/component 组合的金额。
如果您的 table 中没有 id/component 的重复组合,则此查询有效。如果每个组合确实有多个值,则可以在前两列上使用聚合函数,例如 group by
,在金额列上使用 sum()
。
结果:
id | component | amount |
---|---|---|
123 | C1 | 12 |
123 | C2 | 15.5 |
123 | C3 | 13 |
234 | C1 | 544 |
234 | C2 | 546 |
234 | C3 | 0 |
334 | C1 | 13 |
334 | C2 | 0 |
334 | C3 | 0 |
445 | C1 | 142 |
445 | C2 | 0 |
445 | C3 | 0 |
虚拟数据:
CREATE TABLE table1 (
id int(11),
component varchar(10),
amount float(5,1)
);
INSERT INTO table1 VALUES
(123, 'C1', 12),
(123, 'C2', 15.5),
(123, 'C3', 13),
(234, 'C1', 544),
(234, 'C2', 546),
(445, 'C1', 142),
(334, 'C1', 13);
您需要 CROSS
连接不同的 ID
到不同的 COMPONENT
和 LEFT
连接到 table:
SELECT i.ID, c.COMPONENT,
COALESCE(t.AMOUNT, 0) AMOUNT
FROM (SELECT DISTINCT ID FROM tablename) i
CROSS JOIN (SELECT DISTINCT COMPONENT FROM tablename) c
LEFT JOIN tablename t ON t.ID = i.ID AND t.COMPONENT = c.COMPONENT
ORDER BY i.ID, c.COMPONENT;
参见demo。