从垂直行中选择记录并转换水平行
Posted
技术标签:
【中文标题】从垂直行中选择记录并转换水平行【英文标题】:Select records from vertical row and transform horizontal row 【发布时间】:2021-09-24 18:59:06 【问题描述】:我正在处理 SQL Server 查询,以获取将处理多个任务代码的用户列表的最后一个 Badge_In_Out_Time。
task_mgmt - 表名
表格列如下
Task_Sn | UserName | Task_Code | Action | Badge_IN_OUT_TIME |
---|---|---|---|---|
1 | Andy | BLOG | START | 2021-07-15 08:11:45.000 |
2 | Andy | BLOG | END | 2021-07-15 10:11:45.000 |
3 | Becky | ACCTS | START | 2021-07-15 11:11:45.000 |
4 | Chris | TAX | START | 2021-07-15 12:11:45.000 |
5 | Andy | SOCMEDIA | START | 2021-07-15 12:15:45.000 |
6 | Becky | ACCTS | END | 2021-07-15 12:25:45.000 |
我正在排除结果
UserName | Task_Code | Badge_IN_TIME | Badge_OUT_TIME |
---|---|---|---|
Andy | BLOG | 2021-07-15 08:11:45.000 | 2021-07-15 10:11:45.000 |
Becky | ACCTS | 2021-07-15 11:11:45.000 | 2021-07-15 12:25:45.000 |
Chris | TAX | 2021-07-15 12:11:45.000 | |
Andy | SOCMEDIA | 2021-07-15 12:15:45.000 |
我真的想不出任何关于这个的问题。我是 SQL 的初学者,我知道 CRUD 操作。这对我来说似乎超级复杂。
Select UserName,
Task_Code,
Badge_In_Time,
Badge_Out_Time
from task_mgmt
order by Badge_IN_OUT_TIME desc
【问题讨论】:
根据问题指南,请展示您的尝试并告诉我们您发现了什么(在本网站或其他地方)以及为什么它不能满足您的需求。 我真的想不出任何关于这个的查询。我是 SQL 的初学者,我知道 CRUD 操作。这对我来说似乎超级复杂。 【参考方案1】:只需通过将行聚合到所需级别(UserName
、TaskCode
)然后使用MAX
或MIN(CASE WHEN .... END)
进行旋转来进行简单的旋转
像这样:
SELECT
tm.UserName
,tm.Task_Code
,MIN(CASE WHEN tm.Action = 'START' THEN tm.Badge_IN_OUT_TIME ELSE NULL END) AS Badge_IN_TIME
,MAX(CASE WHEN tm.Action = 'END' THEN tm.Badge_IN_OUT_TIME ELSE NULL END) AS Badge_OUT_TIME
FROM
task_mgmt AS tm
GROUP BY
tm.UserName
,tm.Task_Code
【讨论】:
谢谢。我会尝试这个解决方案并让你知道。真的很欣赏。【参考方案2】:这是一种间隙和岛屿问题,这些岛屿是START
和END
的对。
有多种解决方案。在这里,我假设START
总是定义每个组的开头,可能有也可能没有END
。
我们可以使用带窗口的COUNT
,按UserName
和Task_Code
划分来计算每个岛的分组数。然后,我们也只需按新的分组编号进行分组,并旋转时间戳。
SELECT
t.UserName,
t.Task_Code
MIN(CASE WHEN t.Action = 'START' THEN t.Badge_IN_OUT_TIME END) Badge_IN_TIME,
MAX(CASE WHEN t.Action = 'END' THEN t.Badge_IN_OUT_TIME END) Badge_OUT_TIME
FROM (
SELECT *,
COUNT(CASE WHEN t.Action = 'START' THEN 1 END) OVER
(PARTITION BY t.UserName, t.Task_Code
ORDER BY t.Badge_IN_OUT_TIME ROWS UNBOUNDED PRECEDING) grp
FROM task_mgmt t
) t
GROUP BY
t.UserName,
t.Task_Code
t.grp;
【讨论】:
以上是关于从垂直行中选择记录并转换水平行的主要内容,如果未能解决你的问题,请参考以下文章
带有 IntputLabel 和 Input 的 Material UI 网格放置在水平行中:如何要求垂直对齐位于标签的中间?