将每次出现的 select 放入新列 (SQL)
Put each occurence of a select in a new column (SQL)
我有一个 SQL 数据库,其中包含一个由 4 列组成的简单 table。这些列是:“名称”、“时间”、“日期”和“月份”。我必须在视图中显示人员“A”在同一天的“时间”B 做了多少次。使用 select,我会将每次出现作为一个新行,例如
但我想要类似的东西
在 SQL 中可以吗?
如果你不知道每天的最大次数,那么使用group_concat()
:
select name, day, group_concat(time) as times
from t
group by name, day;
如果这样做,您可以使用条件聚合:
select name, day,
max(case when seqnum = 1 then time end) as time_1,
max(case when seqnum = 2 then time end) as time_2,
max(case when seqnum = 3 then time end) as time_3,
max(case when seqnum = 4 then time end) as time_4
from (select t.*,
row_number() over (partition by name, date order by time) as seqnum
from t
) t
group by name, day;
如果你使用 mysql 5.x 你可以使用一个枢轴 table
CREATE TABLE table1 (
`Name` VARCHAR(1),
`Time` VARCHAR(5),
`Day` VARCHAR(4)
);
INSERT INTO table1
(`Name`, `Time`, `Day`)
VALUES
('A', '11:00', '1/10'),
('A', '12:00', '1/10'),
('A', '13:00', '1/10'),
('A', '17:00', '1/10'),
('A', '10:00', '2/10'),
('A', '12:00', '2/10'),
('A', '14:00', '2/10'),
('A', '17:00', '2/10');
SELECT
`Name`,
IF(@date = `Day`,@rn:= @rn +1,@rn:= 1) rn
,`Time`
,@date := `Day` 'Day'
FROM table1, (SELECT @rn:= 0,@date := '')a
ORDER BY `Name`,`Day`,`Time`
Name | rn | Time | Day
:--- | -: | :---- | :---
A | 1 | 11:00 | 1/10
A | 2 | 12:00 | 1/10
A | 3 | 13:00 | 1/10
A | 4 | 17:00 | 1/10
A | 1 | 10:00 | 2/10
A | 2 | 12:00 | 2/10
A | 3 | 14:00 | 2/10
A | 4 | 17:00 | 2/10
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT('MAX(IF(s.`rn` = "', `rn`,'", `Time`,"")) AS time_',rn)
) INTO @sql
FROM (SELECT
`Name`,
IF(@date = `Day`,@rn:= @rn +1,@rn:= 1) rn
,`Time`
,@date := `Day` 'Day'
FROM table1, (SELECT @rn:= 0,@date := '')a
ORDER BY `Name`,`Day`,`Time`) t1;
SET @sql = CONCAT('SELECT `Name`, ', @sql, ' ,`Day`
FROM (SELECT
`Name`,
IF(@date = `Day`,@rn:= @rn +1,@rn:= 1) rn
,`Time`
,@date := `Day` "Day"
FROM table1, (SELECT @rn:= 0,@date := "") a
ORDER BY `Name`,`Day`,`Time`) s
GROUP BY s.`Name`,s.`Day`
ORDER BY s.`Name`,s.`Day`');
#SELECT @sql;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Name | time_1 | time_2 | time_3 | time_4 | Day
:--- | :----- | :----- | :----- | :----- | :---
A | 11:00 | 12:00 | 13:00 | 17:00 | 1/10
A | 10:00 | 12:00 | 14:00 | 17:00 | 2/10
db<>fiddle here
我有一个 SQL 数据库,其中包含一个由 4 列组成的简单 table。这些列是:“名称”、“时间”、“日期”和“月份”。我必须在视图中显示人员“A”在同一天的“时间”B 做了多少次。使用 select,我会将每次出现作为一个新行,例如
但我想要类似的东西
在 SQL 中可以吗?
如果你不知道每天的最大次数,那么使用group_concat()
:
select name, day, group_concat(time) as times
from t
group by name, day;
如果这样做,您可以使用条件聚合:
select name, day,
max(case when seqnum = 1 then time end) as time_1,
max(case when seqnum = 2 then time end) as time_2,
max(case when seqnum = 3 then time end) as time_3,
max(case when seqnum = 4 then time end) as time_4
from (select t.*,
row_number() over (partition by name, date order by time) as seqnum
from t
) t
group by name, day;
如果你使用 mysql 5.x 你可以使用一个枢轴 table
CREATE TABLE table1 ( `Name` VARCHAR(1), `Time` VARCHAR(5), `Day` VARCHAR(4) ); INSERT INTO table1 (`Name`, `Time`, `Day`) VALUES ('A', '11:00', '1/10'), ('A', '12:00', '1/10'), ('A', '13:00', '1/10'), ('A', '17:00', '1/10'), ('A', '10:00', '2/10'), ('A', '12:00', '2/10'), ('A', '14:00', '2/10'), ('A', '17:00', '2/10');
SELECT `Name`, IF(@date = `Day`,@rn:= @rn +1,@rn:= 1) rn ,`Time` ,@date := `Day` 'Day' FROM table1, (SELECT @rn:= 0,@date := '')a ORDER BY `Name`,`Day`,`Time`
Name | rn | Time | Day :--- | -: | :---- | :--- A | 1 | 11:00 | 1/10 A | 2 | 12:00 | 1/10 A | 3 | 13:00 | 1/10 A | 4 | 17:00 | 1/10 A | 1 | 10:00 | 2/10 A | 2 | 12:00 | 2/10 A | 3 | 14:00 | 2/10 A | 4 | 17:00 | 2/10
SET @sql = NULL; SELECT GROUP_CONCAT(DISTINCT CONCAT('MAX(IF(s.`rn` = "', `rn`,'", `Time`,"")) AS time_',rn) ) INTO @sql FROM (SELECT `Name`, IF(@date = `Day`,@rn:= @rn +1,@rn:= 1) rn ,`Time` ,@date := `Day` 'Day' FROM table1, (SELECT @rn:= 0,@date := '')a ORDER BY `Name`,`Day`,`Time`) t1; SET @sql = CONCAT('SELECT `Name`, ', @sql, ' ,`Day` FROM (SELECT `Name`, IF(@date = `Day`,@rn:= @rn +1,@rn:= 1) rn ,`Time` ,@date := `Day` "Day" FROM table1, (SELECT @rn:= 0,@date := "") a ORDER BY `Name`,`Day`,`Time`) s GROUP BY s.`Name`,s.`Day` ORDER BY s.`Name`,s.`Day`'); #SELECT @sql; PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
Name | time_1 | time_2 | time_3 | time_4 | Day :--- | :----- | :----- | :----- | :----- | :--- A | 11:00 | 12:00 | 13:00 | 17:00 | 1/10 A | 10:00 | 12:00 | 14:00 | 17:00 | 2/10
db<>fiddle here