按顺序排列数据并按值分组

时间:2019-02-23 15:09:59

标签: sql sql-server tsql sql-server-2008

在SQL Server数据仓库表中,按顺序查找给定的详细信息V,T,C group by Shipment_id order by TASK_SEQUENCE_NUMBER,其中TASK_TYPE的顺序为V依次为T和C。

如果依次没有V,T,C的值,则该值为0。如果V,T,C超过一次,我们可以将这些值求和并显示

下面是具有预期结果的表架构和数据,必须将其合并到Task_Main表中具有更多列的存储过程中。

CREATE TABLE [dbo].[Task_Detail]
(
    [Task_Sid] [int] NULL,      
    [Shipment_ID] [decimal](18, 0) NULL,
    [TASK_SEQUENCE_No] [decimal](18, 0) NULL,
    [TASK_TYPE] [varchar](1) NULL,      
    [TASK_DURATION] [decimal](18, 0) NULL,      
    [LOCATION_CODE] [varchar](15) NULL,         
    [TaskStart] [bigint] NULL    
) ON [PRIMARY]

CREATE TABLE [dbo].[Task_Header]
(
    [Task_Sno] [int] NULL,      
    [Shipment_ID] [decimal](18, 0) NULL,
    [Vehicle_Id] [nchar](10) NULL,      
    [DepotVisitStartTime] [datetime2](7) NULL,      
    [Time_V] [bigint] NULL,         
    [Time_T] [bigint] NULL,     
    [Time_C] [bigint] NULL     
) ON [PRIMARY]


INSERT [dbo].[Task_Detail] ([Task_Sid], [Shipment_ID], [TASK_SEQUENCE_No], [TASK_TYPE], [TASK_DURATION], [LOCATION_CODE], [TaskStart]) 
VALUES (1, CAST(1 AS Decimal(18, 0)), CAST(1 AS Decimal(18, 0)), N'K', CAST(20 AS Decimal(18, 0)), N'LC39', 20),
       (2, CAST(1 AS Decimal(18, 0)), CAST(7 AS Decimal(18, 0)), N'L', CAST(21 AS Decimal(18, 0)), N'10019514', 21),
       (3, CAST(1 AS Decimal(18, 0)), CAST(3 AS Decimal(18, 0)), N'L', CAST(58 AS  Decimal(18, 0)), N'LC38', 58),
       (4, CAST(1 AS Decimal(18, 0)), CAST(6 AS Decimal(18, 0)), N'C', CAST(10 AS Decimal(18, 0)), NULL, 10),
       (5, CAST(1 AS Decimal(18, 0)), CAST(8 AS Decimal(18, 0)), N'V', CAST(30 AS Decimal(18, 0)), N'10019514', 30),
       (6, CAST(1 AS Decimal(18, 0)), CAST(10 AS Decimal(18, 0)), N'C', CAST(11 AS Decimal(18, 0)), N'RJC', 11),
       (7, CAST(1 AS Decimal(18, 0)), CAST(9 AS Decimal(18, 0)), N'T', CAST(19 AS Decimal(18, 0)), N'10019027', 19),
       (8, CAST(2 AS Decimal(18, 0)), CAST(7 AS Decimal(18, 0)), N'V', CAST(29 AS Decimal(18, 0)), N'10018952', 29),
       (9, CAST(2 AS Decimal(18, 0)), CAST(4 AS Decimal(18, 0)), N'K', CAST(20 AS Decimal(18, 0)), NULL, 20),
       (10, CAST(2 AS Decimal(18, 0)), CAST(5 AS Decimal(18, 0)), N'V', CAST(0 AS Decimal(18, 0)), N'302', 0),
       (11, CAST(3 AS Decimal(18, 0)), CAST(12 AS Decimal(18, 0)), N'T', CAST(19 AS Decimal(18, 0)), N'10019514', 19),
       (12, CAST(3 AS Decimal(18, 0)), CAST(13 AS Decimal(18, 0)), N'E', CAST(11 AS Decimal(18, 0)), N'10019514', 11),
       (13, CAST(2 AS Decimal(18, 0)), CAST(3 AS Decimal(18, 0)), N'V', CAST(32 AS Decimal(18, 0)), N'', 32),
       (14, CAST(3 AS Decimal(18, 0)), CAST(4 AS Decimal(18, 0)), N'K', CAST(20 AS Decimal(18, 0)), N'10018952', 20),
       (15, CAST(3 AS Decimal(18, 0)), CAST(5 AS Decimal(18, 0)), N'V', CAST(0 AS Decimal(18, 0)), N'LC57', 0),
       (16, CAST(3 AS Decimal(18, 0)), CAST(8 AS Decimal(18, 0)), N'T', CAST(19 AS Decimal(18, 0)), N'10019514', 19),
       (17, CAST(3 AS Decimal(18, 0)), CAST(9 AS Decimal(18, 0)), N'C', CAST(10 AS Decimal(18, 0)), N'10019027', 10),
       (18, CAST(3 AS Decimal(18, 0)), CAST(3 AS Decimal(18, 0)), N'L', CAST(21 AS Decimal(18, 0)), N'LC38', 21),
       (19, CAST(3 AS Decimal(18, 0)), CAST(11 AS Decimal(18, 0)), N'V', CAST(30 AS Decimal(18, 0)), N'10019514', 30),
       (20, CAST(3 AS Decimal(18, 0)), CAST(10 AS Decimal(18, 0)), N'L', CAST(21 AS Decimal(18, 0)), N'10019514', 21),
       (21, CAST(3 AS Decimal(18, 0)), CAST(1 AS Decimal(18, 0)), N'T', CAST(19 AS Decimal(18, 0)), N'LC39', 19),
       (22, CAST(3 AS Decimal(18, 0)), CAST(2 AS Decimal(18, 0)), N'C', CAST(10 AS Decimal(18, 0)), N'302', 10),
       (23, CAST(1 AS Decimal(18, 0)), CAST(2 AS Decimal(18, 0)), N'V', CAST(0 AS Decimal(18, 0)), N'302', 0),
       (24, CAST(1 AS Decimal(18, 0)), CAST(4 AS Decimal(18, 0)), N'V', CAST(29 AS Decimal(18, 0)), N'10018952', 29),
       (25, CAST(1 AS Decimal(18, 0)), CAST(5 AS Decimal(18, 0)), N'T', CAST(19 AS Decimal(18, 0)), N'LC57', 19)
, (26, CAST(3 AS Decimal(18, 0)), CAST(6 AS Decimal(18, 0)), N'L', CAST(58 AS Decimal(18, 0)), N'10019514', 58)
, (27, CAST(3 AS Decimal(18, 0)), CAST(7 AS Decimal(18, 0)), N'V', CAST(29 AS Decimal(18, 0)), N'10019514', 29)
, (28, CAST(2 AS Decimal(18, 0)), CAST(6 AS Decimal(18, 0)), N'L', CAST(58 AS Decimal(18, 0)), N'10018952', 58)
, (29, CAST(2 AS Decimal(18, 0)), CAST(2 AS Decimal(18, 0)), N'L', CAST(35 AS Decimal(18, 0)), NULL, 35)



INSERT [dbo].[Task_Header] ([Task_Sno], [Shipment_ID], [Vehicle_Id], [DepotVisitStartTime], [Time_V], [Time_T], [Time_C]) VALUES 
(1, CAST(1 AS Decimal(18, 0)), N'TN1       ', CAST(N'2019-02-15T07:25:33.0000000' AS DateTime2), NULL, NULL, NULL)
,(2, CAST(1 AS Decimal(18, 0)), N'TN1       ', CAST(N'2019-02-15T07:25:33.0000000' AS DateTime2), NULL, NULL, NULL)
,(3, CAST(1 AS Decimal(18, 0)), N'TN1       ', CAST(N'2019-02-15T07:25:33.0000000' AS DateTime2), NULL, NULL, NULL)
,(4, CAST(1 AS Decimal(18, 0)), N'TN1       ', CAST(N'2019-02-15T07:25:33.0000000' AS DateTime2), NULL, NULL, NULL)
,(5, CAST(2 AS Decimal(18, 0)), N'KA2       ', CAST(N'2019-02-15T06:12:52.0000000' AS DateTime2), NULL, NULL, NULL)
,(6, CAST(2 AS Decimal(18, 0)), N'KA2       ', CAST(N'2019-02-15T06:12:52.0000000' AS DateTime2), NULL, NULL, NULL)
,(7, CAST(3 AS Decimal(18, 0)), N'AP3       ', CAST(N'2019-02-15T06:32:52.0000000' AS DateTime2), NULL, NULL, NULL)
,(8, CAST(3 AS Decimal(18, 0)), N'AP3       ', CAST(N'2019-02-15T06:32:52.0000000' AS DateTime2), NULL, NULL, NULL)
,(9, CAST(3 AS Decimal(18, 0)), N'AP3       ', CAST(N'2019-02-15T13:12:21.0000000' AS DateTime2), NULL, NULL, NULL)

使用过滤器的预期结果:

按Shipment_ID,TASK_SEQUENCE_NUMBER过滤器对数据进行排序,其中Location_code <>'RJC'TaskMaster和TaskDetails的联接为Shipment_id TASK_TYPE在给定序列中应为V,下一个立即数T,下一个立即数C仅考虑输出

样本数据:结果 对于Shipment_ID 1,我们具有列V:59,它是给定Shipment_Id结果数据的“ V”值之和,是按shipping_id分组的,shipment_id是sequence_number 4和8 = 29 + 30 = 59的总和 T列在V之后按顺序出现,它是sequence_number 5和9 = 19 +19 = 38的总和 C列以T的顺序出现,它是sequence_number 6和10 = 10 +11 = 21的和 对于货件2,我们在VTC序列中没有任务类型 对于装运3,我们在V T C Secquence中为No 7,8,9分配了Task Type,其中值29,19,10仅一次,并且该值发送到主表

Sample data with marking which has to considered

Expected Result
-----------------------------
Sno Shipment_ID Vehicle ID  DepotVisitStartTime         V   T   C
1   1           TN1         2019-02-15 07:25:33.0000000 59  38  21
2   1           TN1         2019-02-15 07:25:33.0000000 59  38  21
3   1           TN1         2019-02-15 07:25:33.0000000 59  38  21
4   1           TN1         2019-02-15 07:25:33.0000000 59  38  21
5   2           KA2         2019-02-15 06:12:52.0000000 0   0   0
6   2           KA2         2019-02-15 06:12:52.0000000 0   0   0
7   3           AP3         2019-02-15 06:32:52.0000000 29  19  10
8   3           AP3         2019-02-15 06:32:52.0000000 29  19  10
9   3           AP3         2019-02-15 13:12:21.0000000 29  19  10

这些列是下面文章的续篇,我想要一个存储的过程将数据插入Task_Master表中[给定ID的总日期和数量在同一表中

2 个答案:

答案 0 :(得分:3)

这将以select的形式生成您想要的输出:

select h.*, coalesce(d.v, 0) as v,
       coalesce(d.t, 0) as t, coalesce(d.c, 0) as c
from task_header h outer apply
     (select sum(dv.task_duration) as v,
             sum(dt.task_duration) as t,
             sum(dc.task_duration) as c
      from task_detail dv join
           task_detail dt
           on dt.Shipment_ID = dv.Shipment_ID and dt.TASK_SEQUENCE_No = dv.TASK_SEQUENCE_No + 1 join
           task_detail dc
           on dc.Shipment_ID = dt.Shipment_ID and dc.TASK_SEQUENCE_No = dt.TASK_SEQUENCE_No + 1 
      where dv.Shipment_ID = h.Shipment_ID and dv.task_type = 'V' and dt.task_type = 'T' and dc.task_type = 'C'
     ) d;

这会进行更新:

update h
    set time_v = coalesce(d.v, 0),
        time_t = coalesce(d.t, 0),
        time_c = coalesce(d.c, 0)
from task_header h outer apply
     (select sum(dv.task_duration) as v,
             sum(dt.task_duration) as t,
             sum(dc.task_duration) as c
      from task_detail dv join
           task_detail dt
           on dt.Shipment_ID = dv.Shipment_ID and dt.TASK_SEQUENCE_No = dv.TASK_SEQUENCE_No + 1 join
           task_detail dc
           on dc.Shipment_ID = dt.Shipment_ID and dc.TASK_SEQUENCE_No = dt.TASK_SEQUENCE_No + 1 
      where dv.Shipment_ID = h.Shipment_ID and dv.task_type = 'V' and dt.task_type = 'T' and dc.task_type = 'C'
     ) d;

Here是db <>小提琴。

答案 1 :(得分:0)

如果您拥有SQL Server 2012+(我建议您这样做,2008年将完全失去支持),则可以使用LEAD来实现:

WITH CTE AS(
    SELECT TD.Task_Sid,
           TD.Shipment_ID,
           TD.TASK_SEQUENCE_No,
           TD.TASK_TYPE,
           TD.TASK_DURATION,
           LEAD(TASK_TYPE,1) OVER (PARTITION BY Shipment_ID ORDER BY TASK_SEQUENCE_No) AS NextType,
           LEAD(TASK_DURATION,1) OVER (PARTITION BY Shipment_ID ORDER BY TASK_SEQUENCE_No) AS NextDuration,
           LEAD(TASK_TYPE,2) OVER (PARTITION BY Shipment_ID ORDER BY TASK_SEQUENCE_No) AS NextNextType,
           LEAD(TASK_DURATION,2) OVER (PARTITION BY Shipment_ID ORDER BY TASK_SEQUENCE_No) AS NextNextDuration
    FROM Task_Detail TD),
VTC AS(
    SELECT *
    FROM CTE
    WHERE TASK_TYPE = 'V'
      AND NextType = 'T'
      AND NextNextType = 'C'
)
SELECT TH.Task_Sno,
       TH.Shipment_ID,
       TH.Vehicle_Id,
       TH.DepotVisitStartTime,
       ISNULL(SUM(TASK_DURATION),0) AS V,
       ISNULL(SUM(NextDuration),0) AS T,
       ISNULL(SUM(NextNextDuration),0) AS C
FROM Task_Header TH
     LEFT JOIN VTC ON TH.Shipment_ID = VTC.Shipment_ID
GROUP BY TH.Task_Sno,
         TH.Shipment_ID,
         TH.Vehicle_Id,
         TH.DepotVisitStartTime;

如果没有,那么您将需要对表Task_Detail进行3次扫描,这将花费更多:

WITH VTC AS(
    SELECT TD1.Task_Sid,
           TD1.Shipment_ID,
           TD1.TASK_SEQUENCE_No,
           TD1.TASK_TYPE,
           TD1.TASK_DURATION,
           TD2.TASK_TYPE AS NextType,
           TD2.TASK_DURATION  AS NextDuration,
           TD3.TASK_TYPE AS NextNextType,
           TD3.TASK_DURATION  AS NextNextDuration
    FROM Task_Detail TD1
         JOIN Task_Detail TD2 ON TD1.Shipment_ID = TD2.Shipment_ID
                             AND TD1.TASK_SEQUENCE_No +1 = TD2.TASK_SEQUENCE_No
         JOIN Task_Detail TD3 ON TD1.Shipment_ID = TD3.Shipment_ID
                             AND TD1.TASK_SEQUENCE_No +2 = TD3.TASK_SEQUENCE_No
    WHERE TD1.TASK_TYPE = 'V'
      AND TD2.TASK_TYPE = 'T'
      AND TD3.TASK_TYPE = 'C')
SELECT TH.Task_Sno,
       TH.Shipment_ID,
       TH.Vehicle_Id,
       TH.DepotVisitStartTime,
       ISNULL(SUM(TASK_DURATION),0) AS V,
       ISNULL(SUM(NextDuration),0) AS T,
       ISNULL(SUM(NextNextDuration),0) AS C
FROM Task_Header TH
     LEFT JOIN VTC ON TH.Shipment_ID = VTC.Shipment_ID
GROUP BY TH.Task_Sno,
         TH.Shipment_ID,
         TH.Vehicle_Id,
         TH.DepotVisitStartTime;