Return 显示记录中最后已知值 (MAX DateTime) 的列 table 每行的 ID - SQL
Return a column that displays the last known value (MAX DateTime) from a record table for each row by ID - SQL
我知道以前有人问过类似的问题,我会在底部添加一些链接,但无法解决我的查询问题。
我想计算一个视图中的 2 列,其中 return 每个人的最后已知状态(状态 A 和状态 B)(状态变化 DateTime
)。
我在 date_time
上加入了两条记录 table,其中包含有关个人状态随时间变化的信息。当状态 B 发生变化时,我想知道一个人状态 A 的最新值,反之亦然。例如,当一个人的状态从“饥饿”变为“悲伤”时,他们最新(或当前)的 StatusB(活跃?)是什么。
我当前的查询 returns a table:
DateTime
ID
StatusA_Old
StatusA_New
StatusB_Old
StatusB_New
2021-02-01 23:57:20.000
1001
NULL
Hungry
NULL
Active
2021-02-02 23:57:20.000
1002
NULL
Sad
NULL
Active
2021-02-03 23:57:20.000
1001
Hungry
Happy
NULL
NULL
2021-02-04 23:57:20.000
1002
NULL
NULL
Active
Inactive
我想return一个table:
DateTime
ID
StatusA_Old
StatusA_New
StatusA_Current
StatusB_Old
StatusB_New
StatusB_Current
2021-02-01 23:57:20.000
1001
NULL
Hungry
Hungry
NULL
Active
Active
2021-02-02 23:57:20.000
1002
NULL
Sad
Sad
NULL
Active
Active
2021-02-03 23:57:20.000
1001
Hungry
Happy
Happy
NULL
NULL
Active
2021-02-04 23:57:20.000
1002
NULL
NULL
Sad
Active
Inactive
Inactive
我尝试了什么?
我已经有大约 7 次尝试使用子查询 and/or 将 table 自身连接到 return StatusA_New/StatusB_New 在 MAX(DateTime ) 的两个原始 tables.
我最接近的大概是这个:
WITH T AS
(
SELECT
A.DateTime, A.ID, A.StatusA_New
FROM A
)
SELECT
A.DateTime, A.ID, A.StatusA_Old,
A.StatusB_New, T.StatusA_New AS StatusA_Current
FROM
A
LEFT JOIN
T ON (A.DateTime <= T.DateTime) AND (A.ID = T.ID)
请记住,我当前的查询甚至没有查看 B 中的状态变化,也没有处理示例 tables 中显示的加入 DateTime table。
加入的Table AB使用以下查询:
/*example tables*/
create table A
(
A_DateTime datetime,
ID varchar(10),
StatusA_Old varchar(10),
StatusA_New varchar(10)
)
create table B
(
B_DateTime datetime,
ID varchar(10),
StatusB_Old varchar(10),
StatusB_New varchar(10)
)
insert into A values
('2021-02-01 23:57:20.000', 1001, NULL, 'Hungry'),
('2021-02-02 23:57:20.000', 1002, NULL, 'Sad'),
('2021-02-03 23:57:20.000', 1001, 'Hungry', 'Happy')
insert into B values
('2021-02-01 23:57:20.000', 1001, NULL, 'Active'),
('2021-02-02 23:57:20.000', 1002, NULL, 'Active'),
('2021-02-04 23:57:20.000', 1002, 'Active', 'Inactive')
SELECT
CASE
WHEN A.A_DateTime IS NULL THEN B.B_DateTime
ELSE A.A_DateTime
END AS DateTime,
CASE
WHEN A.ID IS NULL THEN B.ID
ELSE A.ID
END AS ID,
StatusA_Old, StatusA_New,
StatusB_Old, StatusB_New
FROM
A
FULL OUTER JOIN
B ON A.A_DateTime = B.B_DateTime
类似问题:
- Retrieve last known value for each column of a row
- SQL: Select the last record for each day given datetime
- Retrieving the last record in each group - MySQL
- SQL: How to fill empty cells with previous row value?
- 也可能与此问题有关(正如另一位用户提到的)https://www.itprotoday.com/sql-server/last-non-null-puzzle
对现有查询使用 CTE,然后使用子查询从 cte
中获取最新的 NOT NULL
值
WITH CTE
AS
(
SELECT COALESCE(A.A_DateTime, B.B_DateTime) AS DateTime
,COALESCE(A.ID, B.ID) AS ID
,StatusA_Old
,StatusA_New
,StatusB_Old
,StatusB_New
FROM A
FULL OUTER JOIN B
ON A.ID = B.ID
AND A.A_DateTime = B.B_DateTime
)
SELECT *
,(SELECT TOP 1 x.StatusA_New
FROM CTE x
WHERE x.ID = c.ID
AND x.DateTime <= c.DateTime
AND x.StatusA_New IS NOT NULL
ORDER BY x.DateTime DESC) AS StatusA_Current
,(SELECT TOP 1 x.StatusB_New
FROM CTE x
WHERE x.ID = c.ID
AND x.DateTime <= c.DateTime
AND x.StatusB_New IS NOT NULL
ORDER BY x.DateTime DESC) AS StatusB_Current
FROM CTE c
ORDER BY [DateTime]
我知道以前有人问过类似的问题,我会在底部添加一些链接,但无法解决我的查询问题。
我想计算一个视图中的 2 列,其中 return 每个人的最后已知状态(状态 A 和状态 B)(状态变化 DateTime
)。
我在 date_time
上加入了两条记录 table,其中包含有关个人状态随时间变化的信息。当状态 B 发生变化时,我想知道一个人状态 A 的最新值,反之亦然。例如,当一个人的状态从“饥饿”变为“悲伤”时,他们最新(或当前)的 StatusB(活跃?)是什么。
我当前的查询 returns a table:
DateTime | ID | StatusA_Old | StatusA_New | StatusB_Old | StatusB_New |
---|---|---|---|---|---|
2021-02-01 23:57:20.000 | 1001 | NULL | Hungry | NULL | Active |
2021-02-02 23:57:20.000 | 1002 | NULL | Sad | NULL | Active |
2021-02-03 23:57:20.000 | 1001 | Hungry | Happy | NULL | NULL |
2021-02-04 23:57:20.000 | 1002 | NULL | NULL | Active | Inactive |
我想return一个table:
DateTime | ID | StatusA_Old | StatusA_New | StatusA_Current | StatusB_Old | StatusB_New | StatusB_Current |
---|---|---|---|---|---|---|---|
2021-02-01 23:57:20.000 | 1001 | NULL | Hungry | Hungry | NULL | Active | Active |
2021-02-02 23:57:20.000 | 1002 | NULL | Sad | Sad | NULL | Active | Active |
2021-02-03 23:57:20.000 | 1001 | Hungry | Happy | Happy | NULL | NULL | Active |
2021-02-04 23:57:20.000 | 1002 | NULL | NULL | Sad | Active | Inactive | Inactive |
我尝试了什么?
我已经有大约 7 次尝试使用子查询 and/or 将 table 自身连接到 return StatusA_New/StatusB_New 在 MAX(DateTime ) 的两个原始 tables.
我最接近的大概是这个:
WITH T AS
(
SELECT
A.DateTime, A.ID, A.StatusA_New
FROM A
)
SELECT
A.DateTime, A.ID, A.StatusA_Old,
A.StatusB_New, T.StatusA_New AS StatusA_Current
FROM
A
LEFT JOIN
T ON (A.DateTime <= T.DateTime) AND (A.ID = T.ID)
请记住,我当前的查询甚至没有查看 B 中的状态变化,也没有处理示例 tables 中显示的加入 DateTime table。
加入的Table AB使用以下查询:
/*example tables*/
create table A
(
A_DateTime datetime,
ID varchar(10),
StatusA_Old varchar(10),
StatusA_New varchar(10)
)
create table B
(
B_DateTime datetime,
ID varchar(10),
StatusB_Old varchar(10),
StatusB_New varchar(10)
)
insert into A values
('2021-02-01 23:57:20.000', 1001, NULL, 'Hungry'),
('2021-02-02 23:57:20.000', 1002, NULL, 'Sad'),
('2021-02-03 23:57:20.000', 1001, 'Hungry', 'Happy')
insert into B values
('2021-02-01 23:57:20.000', 1001, NULL, 'Active'),
('2021-02-02 23:57:20.000', 1002, NULL, 'Active'),
('2021-02-04 23:57:20.000', 1002, 'Active', 'Inactive')
SELECT
CASE
WHEN A.A_DateTime IS NULL THEN B.B_DateTime
ELSE A.A_DateTime
END AS DateTime,
CASE
WHEN A.ID IS NULL THEN B.ID
ELSE A.ID
END AS ID,
StatusA_Old, StatusA_New,
StatusB_Old, StatusB_New
FROM
A
FULL OUTER JOIN
B ON A.A_DateTime = B.B_DateTime
类似问题:
- Retrieve last known value for each column of a row
- SQL: Select the last record for each day given datetime
- Retrieving the last record in each group - MySQL
- SQL: How to fill empty cells with previous row value?
- 也可能与此问题有关(正如另一位用户提到的)https://www.itprotoday.com/sql-server/last-non-null-puzzle
对现有查询使用 CTE,然后使用子查询从 cte
NOT NULL
值
WITH CTE
AS
(
SELECT COALESCE(A.A_DateTime, B.B_DateTime) AS DateTime
,COALESCE(A.ID, B.ID) AS ID
,StatusA_Old
,StatusA_New
,StatusB_Old
,StatusB_New
FROM A
FULL OUTER JOIN B
ON A.ID = B.ID
AND A.A_DateTime = B.B_DateTime
)
SELECT *
,(SELECT TOP 1 x.StatusA_New
FROM CTE x
WHERE x.ID = c.ID
AND x.DateTime <= c.DateTime
AND x.StatusA_New IS NOT NULL
ORDER BY x.DateTime DESC) AS StatusA_Current
,(SELECT TOP 1 x.StatusB_New
FROM CTE x
WHERE x.ID = c.ID
AND x.DateTime <= c.DateTime
AND x.StatusB_New IS NOT NULL
ORDER BY x.DateTime DESC) AS StatusB_Current
FROM CTE c
ORDER BY [DateTime]