MSSQL 排序和连接数据是状态
MSSQL sort and concatenate data be state
是否可以像我的示例那样对数据进行排序?
我想将 start/stop
或 start/error
状态连接成一行。
我尝试了 pivot table,但仍然不知道如何定义它以使其工作。因为一个订单可能有更多的错误或人工,但完整的订单以 stop
结尾
ID LaborID OrderNr StateID State OrderStatusDate
102610 15784158 OPT2201652 1 start 28.01.2022 08:18
102625 15784158 OPT2201652 0 stop 28.01.2022 09:15
102630 15784158 OPT2201655 1 start 28.01.2022 09:31
102632 15784158 OPT2201655 0 stop 28.01.2022 09:43
101519 10134088 OPT2134651 1 start 11.01.2022 14:42
101524 10134088 OPT2134651 2 error 11.01.2022 15:27
101612 10134088 OPT2134651 1 start 13.01.2022 09:30
101642 10134088 OPT2134651 2 error 13.01.2022 15:01
101783 10134088 OPT2134651 1 start 17.01.2022 12:44
101800 10134088 OPT2134651 0 stop 17.01.2022 14:19
101646 10134088 OPT2134787 1 start 14.01.2022 07:56
101661 10134088 OPT2134787 0 stop 14.01.2022 09:03
为此:
LaborID OrderNr start stop error minutes
15784158 OPT2201652 28.01.2022 08:18 28.01.2022 09:15 0:57
15784158 OPT2201655 28.01.2022 09:31 28.01.2022 09:43 0:12
10134088 OPT2134651 11.01.2022 14:42 11.01.2022 15:27 0:45
10134088 OPT2134651 13.01.2022 09:30 13.01.2022 15:01 5:31
10134088 OPT2134651 17.01.2022 12:44 17.01.2022 14:19 1:35
10134088 OPT2134787 14.01.2022 07:56 14.01.2022 09:03 1:07
您可以使用一些 CASE 或子查询来做到这一点...
这是带有子查询的版本
SELECT DISTINCT LaborID, OrderNr,
(SELECT OrderStatusDate FROM T AS Tin WHERE Tin.LaborID = Tout.Labor_ID AND Tin.OrderNr = Tout.OrderNr AND StateID = 1) AS start,
(SELECT OrderStatusDate FROM T AS Tin WHERE Tin.LaborID = Tout.Labor_ID AND Tin.OrderNr = Tout.OrderNr AND StateID = 0) AS stop,
(SELECT OrderStatusDate FROM T AS Tin WHERE Tin.LaborID = Tout.Labor_ID AND Tin.OrderNr = Tout.OrderNr AND StateID = 2) AS error
FROM T AS Tout
您不需要 self-join,您可以使用 window 函数
一次扫描
WITH NextValues AS (
SELECT *,
NextState = LEAD(State) OVER (PARTITION BY LaborID ORDER BY OrderStatusDate),
NextDate = LEAD(OrderStatusDate) OVER (PARTITION BY LaborID ORDER BY OrderStatusDate)
FROM YourTable t
)
SELECT
LaborID,
OrderNr,
start = OrderStatusDate,
stop = CASE WHEN NextState = 'stop' THEN NextDate END,
error = CASE WHEN NextState = 'error' THEN NextDate END,
minutes = DATEDIFF(minute, OrderStatusDate, NextDate)
FROM NextValues t
WHERE State = 'start';
是否可以像我的示例那样对数据进行排序?
我想将 start/stop
或 start/error
状态连接成一行。
我尝试了 pivot table,但仍然不知道如何定义它以使其工作。因为一个订单可能有更多的错误或人工,但完整的订单以 stop
ID LaborID OrderNr StateID State OrderStatusDate
102610 15784158 OPT2201652 1 start 28.01.2022 08:18
102625 15784158 OPT2201652 0 stop 28.01.2022 09:15
102630 15784158 OPT2201655 1 start 28.01.2022 09:31
102632 15784158 OPT2201655 0 stop 28.01.2022 09:43
101519 10134088 OPT2134651 1 start 11.01.2022 14:42
101524 10134088 OPT2134651 2 error 11.01.2022 15:27
101612 10134088 OPT2134651 1 start 13.01.2022 09:30
101642 10134088 OPT2134651 2 error 13.01.2022 15:01
101783 10134088 OPT2134651 1 start 17.01.2022 12:44
101800 10134088 OPT2134651 0 stop 17.01.2022 14:19
101646 10134088 OPT2134787 1 start 14.01.2022 07:56
101661 10134088 OPT2134787 0 stop 14.01.2022 09:03
为此:
LaborID OrderNr start stop error minutes
15784158 OPT2201652 28.01.2022 08:18 28.01.2022 09:15 0:57
15784158 OPT2201655 28.01.2022 09:31 28.01.2022 09:43 0:12
10134088 OPT2134651 11.01.2022 14:42 11.01.2022 15:27 0:45
10134088 OPT2134651 13.01.2022 09:30 13.01.2022 15:01 5:31
10134088 OPT2134651 17.01.2022 12:44 17.01.2022 14:19 1:35
10134088 OPT2134787 14.01.2022 07:56 14.01.2022 09:03 1:07
您可以使用一些 CASE 或子查询来做到这一点...
这是带有子查询的版本
SELECT DISTINCT LaborID, OrderNr,
(SELECT OrderStatusDate FROM T AS Tin WHERE Tin.LaborID = Tout.Labor_ID AND Tin.OrderNr = Tout.OrderNr AND StateID = 1) AS start,
(SELECT OrderStatusDate FROM T AS Tin WHERE Tin.LaborID = Tout.Labor_ID AND Tin.OrderNr = Tout.OrderNr AND StateID = 0) AS stop,
(SELECT OrderStatusDate FROM T AS Tin WHERE Tin.LaborID = Tout.Labor_ID AND Tin.OrderNr = Tout.OrderNr AND StateID = 2) AS error
FROM T AS Tout
您不需要 self-join,您可以使用 window 函数
一次扫描WITH NextValues AS (
SELECT *,
NextState = LEAD(State) OVER (PARTITION BY LaborID ORDER BY OrderStatusDate),
NextDate = LEAD(OrderStatusDate) OVER (PARTITION BY LaborID ORDER BY OrderStatusDate)
FROM YourTable t
)
SELECT
LaborID,
OrderNr,
start = OrderStatusDate,
stop = CASE WHEN NextState = 'stop' THEN NextDate END,
error = CASE WHEN NextState = 'error' THEN NextDate END,
minutes = DATEDIFF(minute, OrderStatusDate, NextDate)
FROM NextValues t
WHERE State = 'start';