2017-06-07 10 views
0

O_Diagnosis操作に基づいてグループ番号を生成しようとしています。私は現在のO_Diagnosis操作と次のO_Diagnosis操作の間で操作をグループ化したいと思います。SQL生成グループ番号

問題は、このデータにはグループ化可能な列がないことです。ですから、私はこの列をゼロからほとんど生成する必要があります。

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 

[処理済み時間]列には、SFCが操作を実行した回数がカウントされます。そのため、O_SF_WRAPの例では1が表示され、次回にO_DiagnosisからSFCが返された場合は2に変更されます。

これを実現するには、関数または多分SQLビューを作ることはできますか?これは、これまでの私のコードです

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] 
+0

目的の出力の最後の2行でグループ化が「1」にリセットされるのはなぜですか? – iamdave

+0

診断ステップの間の行は、廃棄物と労働としてカウントされ、残りは良品と見なされた後にカウントされます。だから私はこれを数えなければなりません。しかし、私は報告ソリューションでこれを行うことができます.. – hvdbunte

答えて

0

私がなぜわからない私は、私がこれまで持っていることは、これは、同じSFC用されているSQL Server 2012

を使用していますあなたのグループ番号は、目的の出力の末尾に1にリセットされますが、それがタイプミスの場合は、row_numbersumという単純なウィンドウを使ってTimes_processedとそれぞれ必要な `Diagnosis_group_nr 'の番号を得ることができます:

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にこれらの列を追加し、彼らなります一度にデータセット全体で正しく計算してください。

+0

ありがとうございました。 sumとcase文を使用することが可能であることはわかりませんでした。 これはとても簡単です! – hvdbunte

関連する問題