SQL生成组号

时间:2017-06-07 20:23:15

标签: sql sql-server tsql sql-server-2012

我尝试根据O_Diagnosis操作生成一个组号。我想将当前和下一个O_Diagnosis操作之间的操作分组。

问题是这些数据没有任何支持分组的列。所以我需要几乎从头开始生成这个列。我想要实现的目标如下:

Site SFC    Date Time           Operation          Times_processed  Diagnosis_group_nr
P500 B218YW 2017-03-21 10:16:23 O_SF_WRAP          1                1
P500 B218YW 2017-03-23 06:07:53 O_SF_WRAP_CURE     1                1
P500 B218YW 2017-03-23 14:23:41 O_DIAGNOSIS        1                2
P500 B218YW 2017-03-28 10:07:55 O_SF_WRAP          2                2
P500 B218YW 2017-03-28 15:02:21 O_SF_WRAP_CURE     2                2
P500 B218YW 2017-03-29 20:38:06 O_DIAGNOSIS        2                3
P500 B218YW 2017-03-29 20:39:15 O_DIAGNOSIS        3                4
P500 B218YW 2017-04-27 08:43:53 O_SF_WRAP          3                4
P500 B218YW 2017-04-27 12:43:25 O_SF_WRAP_CURE     3                4
P500 B218YW 2017-04-27 13:05:16 O_SF_PCA_ASSEMBLY  1                4
P500 B218YW 2017-04-27 13:19:15 O_DIAGNOSIS        4                5
P500 B218YW 2017-04-27 15:23:09 O_SF_PCA_ASSEMBLY  2                5
P500 B218YW 2017-04-27 16:10:32 O_SF_ELEC_INT_TEST 1                1
P500 B218YW 2017-04-27 22:16:23 O_RECORD_REVIEW    1                1

The Times处理列计算SFC执行操作的频率。这就是为什么你看到1为O_SF_WRAP的例子,当下次从O_Diagnosis发回SFC时,这将变为2。

是否可以创建一个函数或SQL视图来实现这一目标?我正在使用SQL Server 2012.

到目前为止,对于同一个证监会来说,我目前所拥有的是:

Site SFC    Date Time           Operation          Times_processed  Diagnosis_group_nr
P500 B218YW 2017-03-21 10:16:23 O_SF_WRAP          1                1
P500 B218YW 2017-03-23 06:07:53 O_SF_WRAP_CURE     1                1
P500 B218YW 2017-03-23 14:23:41 O_DIAGNOSIS        1                2
P500 B218YW 2017-03-28 10:07:55 O_SF_WRAP          2                2
P500 B218YW 2017-03-28 15:02:21 O_SF_WRAP_CURE     2                2
P500 B218YW 2017-03-29 20:38:06 O_DIAGNOSIS        2                3
P500 B218YW 2017-03-29 20:39:15 O_DIAGNOSIS        3                3
P500 B218YW 2017-04-27 08:43:53 O_SF_WRAP          3                3
P500 B218YW 2017-04-27 12:43:25 O_SF_WRAP_CURE     3                3
P500 B218YW 2017-04-27 13:05:16 O_SF_PCA_ASSEMBLY  1                4
P500 B218YW 2017-04-27 13:19:15 O_DIAGNOSIS        4                4
P500 B218YW 2017-04-27 15:23:09 O_SF_PCA_ASSEMBLY  2                2
P500 B218YW 2017-04-27 16:10:32 O_SF_ELEC_INT_TEST 1                1
P500 B218YW 2017-04-27 22:16:23 O_RECORD_REVIEW    1                1

到目前为止,这是我的代码:

WITH 
  cteNextRow 
  AS
  (
    SELECT
        opl.[PL SITE]
      , opl.[PL SFC]
      , opl.[Pl End Time Local]
      , opl.[PL OPERATION]
      , LEAD(opl.[PL OPERATION], 1) OVER (PARTITION BY opl.[PL SFC] ORDER BY  opl.[Pl End Time Local])  AS NEXT_OPERATION
      , LEAD(opl.[Pl Times Processed], 1) OVER (PARTITION BY opl.[PL SFC] ORDER BY  opl.[Pl End Time Local])  AS NEXT_TIMES_PROCESSED
      , max(opl.[Pl Times Processed]) OVER (PARTITION BY opl.[PL SFC] ORDER BY opl.[PL SFC], opl.[Pl End Time Local]
        ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) TOTAL_TIMES_PROCESSED
        ,LAST_VALUE(opl.[PL OPERATION]) OVER (PARTITION BY opl.[PL SFC] ORDER BY opl.[PL SFC], opl.[Pl End Time Local]
        ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
        ) as LAST_OPERATION
        ,case when LAST_VALUE(opl.[PL OPERATION]) OVER (PARTITION BY opl.[PL SFC] ORDER BY opl.[PL SFC], opl.[Pl End Time Local]
        ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) not like '%review%'
        then 0
        when LAST_VALUE(opl.[PL OPERATION]) OVER (PARTITION BY opl.[PL SFC] ORDER BY opl.[PL SFC], opl.[Pl End Time Local]
        ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) like '%review%' and max(opl.[Pl Times Processed]) OVER (PARTITION BY opl.[PL SFC] ORDER BY opl.[PL SFC], opl.[Pl End Time Local]
        ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) = 1 
        then 1
        else 9999
        end as REVIEW_IND
    FROM Report1 opl
    where [pl sfc] = 'B218YW'
)
select 
    opl.[pl Site]  AS PROCESS_SITE
      , opl.[PL SFC] AS  PROCESS_SFC
      , opl.[Pl End Time Local] PROCESS_DATE_TIME
      , opl.[PL OPERATION] AS PROCESS_OPERATION
      , cte.NEXT_OPERATION AS PROCESS_NEXT_OPERATION
      , opl.[Pl Times Processed] AS PROCESS_TIMES_PROCESSED
          , CASE   
            when cte.REVIEW_IND = 9999 and cte.NEXT_TIMES_PROCESSED = opl.[Pl Times Processed] and cte.NEXT_OPERATION like '%DIAG%'
              then LEAD(opl.[Pl Times Processed], 1) OVER (PARTITION BY opl.[PL SFC] ORDER BY  opl.[Pl End Time Local])
            when cte.REVIEW_IND = 9999 and cte.NEXT_TIMES_PROCESSED < opl.[Pl Times Processed] 
                then opl.[Pl Times Processed]
            when cte.REVIEW_IND = 9999 and NEXT_TIMES_PROCESSED is null
                then opl.[Pl Times Processed]
            when cte.REVIEW_IND = 9999 and cte.NEXT_TIMES_PROCESSED is not null 
                then cte.NEXT_TIMES_PROCESSED
            else REVIEW_IND
        END  AS Diagnosis_group_nr
FROM Report1 opl
join cteNextRow cte on cte.[PL SITE] = opl.[pl Site] and cte.[PL sfc] = opl.[PL SFC] and cte.[pl operation] = opl.[pl OPERATION] and  opl.[Pl End Time Local] = cte.[Pl End Time Local]

1 个答案:

答案 0 :(得分:0)

我不确定为什么您的分组编号会在所需输出结尾处重置为1,但如果这是拼写错误,您可以使用简单的窗口条件row_numbersum得到Times_processed和`Diagnosis_group_nr&#39;的数量你需要分别:

declare @t table(Site nvarchar(50),SFC nvarchar(50),DateValue datetime,Operation nvarchar(50));
insert into @t values
 ('P500','B218YW','2017-03-21 10:16:23','O_SF_WRAP')
,('P500','B218YW','2017-03-23 06:07:53','O_SF_WRAP_CURE')
,('P500','B218YW','2017-03-23 14:23:41','O_DIAGNOSIS')
,('P500','B218YW','2017-03-28 10:07:55','O_SF_WRAP')
,('P500','B218YW','2017-03-28 15:02:21','O_SF_WRAP_CURE')
,('P500','B218YW','2017-03-29 20:38:06','O_DIAGNOSIS')
,('P500','B218YW','2017-03-29 20:39:15','O_DIAGNOSIS')
,('P500','B218YW','2017-04-27 08:43:53','O_SF_WRAP')
,('P500','B218YW','2017-04-27 12:43:25','O_SF_WRAP_CURE')
,('P500','B218YW','2017-04-27 13:05:16','O_SF_PCA_ASSEMBLY')
,('P500','B218YW','2017-04-27 13:19:15','O_DIAGNOSIS')
,('P500','B218YW','2017-04-27 15:23:09','O_SF_PCA_ASSEMBLY')
,('P500','B218YW','2017-04-27 16:10:32','O_SF_ELEC_INT_TEST')
,('P500','B218YW','2017-04-27 22:16:23','O_RECORD_REVIEW');

select *
    ,row_number() over (partition by Operation order by DateValue) as Times_processed
    ,sum(case when Operation = 'O_DIAGNOSIS' then 1 else 0 end) over (order by DateValue)+1 as Diagnosis_group_nr
from @t
order by DateValue;

输出:

+------+--------+-------------------------+--------------------+-----------------+--------------------+
| Site |  SFC   |        DateValue        |     Operation      | Times_processed | Diagnosis_group_nr |
+------+--------+-------------------------+--------------------+-----------------+--------------------+
| P500 | B218YW | 2017-03-21 10:16:23.000 | O_SF_WRAP          |               1 |                  1 |
| P500 | B218YW | 2017-03-23 06:07:53.000 | O_SF_WRAP_CURE     |               1 |                  1 |
| P500 | B218YW | 2017-03-23 14:23:41.000 | O_DIAGNOSIS        |               1 |                  2 |
| P500 | B218YW | 2017-03-28 10:07:55.000 | O_SF_WRAP          |               2 |                  2 |
| P500 | B218YW | 2017-03-28 15:02:21.000 | O_SF_WRAP_CURE     |               2 |                  2 |
| P500 | B218YW | 2017-03-29 20:38:06.000 | O_DIAGNOSIS        |               2 |                  3 |
| P500 | B218YW | 2017-03-29 20:39:15.000 | O_DIAGNOSIS        |               3 |                  4 |
| P500 | B218YW | 2017-04-27 08:43:53.000 | O_SF_WRAP          |               3 |                  4 |
| P500 | B218YW | 2017-04-27 12:43:25.000 | O_SF_WRAP_CURE     |               3 |                  4 |
| P500 | B218YW | 2017-04-27 13:05:16.000 | O_SF_PCA_ASSEMBLY  |               1 |                  4 |
| P500 | B218YW | 2017-04-27 13:19:15.000 | O_DIAGNOSIS        |               4 |                  5 |
| P500 | B218YW | 2017-04-27 15:23:09.000 | O_SF_PCA_ASSEMBLY  |               2 |                  5 |
| P500 | B218YW | 2017-04-27 16:10:32.000 | O_SF_ELEC_INT_TEST |               1 |                  5 |
| P500 | B218YW | 2017-04-27 22:16:23.000 | O_RECORD_REVIEW    |               1 |                  5 |
+------+--------+-------------------------+--------------------+-----------------+--------------------+

如果您想在多个SiteSFC上运行上述脚本,只需将这些列添加到两个窗口函数的partition by上,它们就可以正确地计算出来整个数据集一气呵成。