Вложенные подзапросы с проблемой логики ROW_NUMBER - PullRequest
4 голосов
/ 22 апреля 2019

(SQL Server 2008) Я пытаюсь отфильтровать трудовые записи из заводской системы учета рабочего времени. Ниже приведен пример данных, приведенных ниже. Столбец TCODE имеет либо «O» (по времени), либо «OF» (по времени выключения). Так, например, Чавес работал над последовательностью 50, Китпулл, в течение 1,06 часа.

Проблема: Когда работник завершает последовательность заданий более чем двумя пролистываниями, система автоматически добавляет одну последнюю пару включенных / выключенных записей (0 часов), которые мне нужно удалить. В случае последовательности 50 Pull Kit и последовательности 400 зенковки есть только два пролистывания (вкл., Затем выкл.), Поэтому никаких дополнительных записей нет. Тем не менее, каждая из других последовательностей имеет две дополнительные строки. В случае последовательности 100 последние две строки в TTIME = 93724 (09:37:24 AM) являются дополнительными строками. Вы можете видеть, что в самой последней строке есть полный код 1, официально отмечающий завершение последовательности работ.

MFGORDNO  SEQUENCE  DESCR                 BADGE  LABOR  TCODE  ENAME   TTIME  CompleteCode
M968460   50        Pull Kit              802    0.00   O      CHAVEZ  82300  NULL
M968460   50        Pull Kit              802    1.06   OF     CHAVEZ  92631  0
M968460   100       Load Parts into AJ    396    0.00   O      CURNEY  150014 NULL
M968460   100       Load Parts into AJ    396    1.00   OF     CURNEY  160022 0
M968460   100       Load Parts into AJ    3169   0.00   O      JONES   84612  NULL
M968460   100       Load Parts into AJ    3169   0.85   OF     JONES   93724  0
M968460   100       Load Parts into AJ    3169   0.00   O      JONES   93724  NULL
M968460   100       Load Parts into AJ    3169   0.00   OF     JONES   93724  1
M968460   200       Transfer Drill Holes  3169   0.00   O      JONES   93737  NULL
M968460   200       Transfer Drill Holes  3169   2.73   OF     JONES   132135 0
M968460   200       Transfer Drill Holes  3169   0.00   O      JONES   132135 NULL
M968460   200       Transfer Drill Holes  3169   0.00   OF     JONES   132135 1
M968460   300       TransDrill Splices    3169   0.00   O      JONES   132153 NULL
M968460   300       TransDrill Splices    3169   3.56   OF     JONES   65539  0
M968460   300       TransDrill Splices    3169   0.00   O      JONES   65539  NULL
M968460   300       TransDrill Splices    3169   0.01   OF     JONES   65539  1
M968460   400       Countersinking        3169   0.00   O      JONES   63102  NULL
M968460   400       Countersinking        3169   2.79   OF     JONES   91716  0
M968460   600       SPLICE STRAPS         3169   0.00   O      JONES   131931 NULL
M968460   600       SPLICE STRAPS         3169   1.17   OF     JONES   143040 0
M968460   600       SPLICE STRAPS         3169   0.00   O      JONES   63456  NULL
M968460   600       SPLICE STRAPS         3169   4.12   OF     JONES   105200 0
M968460   600       SPLICE STRAPS         3169   0.00   O      JONES   105200 NULL
M968460   600       SPLICE STRAPS         3169   0.00   OF     JONES   105200 1

Желаемые результаты: Короче говоря, я пытаюсь использовать один оператор SQL для получения этих результирующих данных.

MFGORDNO  SEQUENCE  DESCR                 BADGE  LABOR  TCODE  ENAME   TTIME  CompleteCode
M968460   50        Pull Kit              802    0.00   O      CHAVEZ  82300  NULL
M968460   50        Pull Kit              802    1.06   OF     CHAVEZ  92631  0
M968460   100       Load Parts into AJ    396    0.00   O      CURNEY  150014 NULL
M968460   100       Load Parts into AJ    396    1.00   OF     CURNEY  160022 0
M968460   100       Load Parts into AJ    3169   0.00   O      JONES   84612  NULL
M968460   100       Load Parts into AJ    3169   0.85   OF     JONES   93724  0
M968460   200       Transfer Drill Holes  3169   0.00   O      JONES   93737  NULL
M968460   200       Transfer Drill Holes  3169   2.73   OF     JONES   132135 0
M968460   300       TransDrill Splices    3169   0.00   O      JONES   132153 NULL
M968460   300       TransDrill Splices    3169   3.56   OF     JONES   65539  0
M968460   400       Countersinking        3169   0.00   O      JONES   63102  NULL
M968460   400       Countersinking        3169   2.79   OF     JONES   91716  0
M968460   600       SPLICE STRAPS         3169   0.00   O      JONES   131931 NULL
M968460   600       SPLICE STRAPS         3169   1.17   OF     JONES   143040 0
M968460   600       SPLICE STRAPS         3169   0.00   O      JONES   63456  NULL
M968460   600       SPLICE STRAPS         3169   4.12   OF     JONES   105200 0

Изначально я начал добавлять номер строки в свой самый внутренний подзапрос, чтобы позже я мог ссылаться на MAX (rn) следующим образом:

SELECT
    *, 
    ROW_NUMBER() OVER (ORDER by TTIME) rn 
FROM
    MySmallData

Из вышеприведенного подзапроса я надеялся затем выбрать все записи из исходных данных, удалив " строки с 1 в CompleteCode и строку прямо над ".

Это скорее проблема стратегии, чем проблема синтаксиса. Я надеялся на некоторые предложения.

Спасибо, John

РЕДАКТИРОВАТЬ: Извините, вот некоторые примеры данных:

CREATE TABLE MySmallData 
(
    [MFGORDNO] NVARCHAR(7),
    [SEQUENCE] INT,
    [DESCR] NVARCHAR(20),
    [BADGE] INT,
    [LABOR] NUMERIC(3, 2),
    [TCODE] NVARCHAR(2),
    [TSTAMP] NVARCHAR(26),
    [ENAME] NVARCHAR(19),
    [TTIME] INT,
    [CompleteCode] INT
);

INSERT INTO MySmallData 
VALUES
    ('M968460',0050,'Pull Kit',802,0,'O','2019-02-26 08:23:00.000004','CHAVEZ',82300,NULL),
    ('M968460',0050,'Pull Kit',802,1.06,'OF','2019-02-26 09:26:30.999995','CHAVEZ',92631,0),
    ('M968460',0100,'Load Parts into AJ',396,0,'O','2019-03-05 15:00:13.999997','CURNEY',150014,NULL),
    ('M968460',0100,'Load Parts into AJ',396,1,'OF','2019-03-05 16:00:22.000001','CURNEY',160022,0),
    ('M968460',0100,'Load Parts into AJ',3169,0,'O','2019-03-06 08:46:12.000003','JONES',84612,NULL),
    ('M968460',0100,'Load Parts into AJ',3169,0.85,'OF','2019-03-06 09:37:23.999998','JONES',93724,0),
    ('M968460',0100,'Load Parts into AJ',3169,0,'O','2019-03-06 09:37:23.999998','JONES',93724,NULL),
    ('M968460',0100,'Load Parts into AJ',3169,0,'OF','2019-03-06 09:37:23.999998','JONES',93724,1),
    ('M968460',0200,'Transfer Drill Holes',3169,0,'O','2019-03-06 09:37:37.000001','JONES',93737,NULL),
    ('M968460',0200,'Transfer Drill Holes',3169,2.73,'OF','2019-03-06 13:21:35.000001','JONES',132135,0),
    ('M968460',0200,'Transfer Drill Holes',3169,0,'O','2019-03-06 13:21:35.000001','JONES',132135,NULL),
    ('M968460',0200,'Transfer Drill Holes',3169,0,'OF','2019-03-06 13:21:35.000001','JONES',132135,1),
    ('M968460',0300,'TransDrill Splices',3169,0,'O','2019-03-06 13:21:52.999998','JONES',132153,NULL),
    ('M968460',0300,'TransDrill Splices',3169,3.56,'OF','2019-03-06 16:55:39','JONES',165539,0),
    ('M968460',0300,'TransDrill Splices',3169,0,'O','2019-03-06 16:55:39','JONES',165539,NULL),
    ('M968460',0300,'TransDrill Splices',3169,0.01,'OF','2019-03-06 16:55:39','JONES',165539,1),
    ('M968460',0400,'Countersinking',3169,0,'O','2019-03-07 06:31:01.999998','JONES',63102,NULL),
    ('M968460',0400,'Countersinking',3169,2.79,'OF','2019-03-07 09:17:15.999996','JONES',91716,0),
    ('M968460',0600,'SPLICE STRAPS',3169,0,'O','2019-03-08 13:19:30.999999','JONES',131931,NULL),
    ('M968460',0600,'SPLICE STRAPS',3169,1.17,'OF','2019-03-08 14:30:39.999997','JONES',143040,0),
    ('M968460',0600,'SPLICE STRAPS',3169,0,'O','2019-03-12 06:34:56.000003','JONES',63456,NULL),
    ('M968460',0600,'SPLICE STRAPS',3169,4.12,'OF','2019-03-12 10:52:00.000002','JONES',105200,0),
    ('M968460',0600,'SPLICE STRAPS',3169,0,'O','2019-03-12 10:52:00.000002','JONES',105200,NULL),
    ('M968460',0600,'SPLICE STRAPS',3169,0,'OF','2019-03-12 10:52:00.000002','JONES',105200,1);

Ответы [ 2 ]

4 голосов
/ 22 апреля 2019

Я думаю, что вы можете сделать это с exists:

select msd.*
from mysmalldata msd
where not ((msd.completecode is null and
            exists (select 1
                    from mysmalldata msd2
                    where msd2.MFGORDNO = msd.MFGORDNO and
                          msd2.sequence = msd.sequence and
                          msd2.badge = msd.badge and
                          msd2.ttime = msd.ttime and
                          msd2.completecode = 1
                   )
            ) or
           (coalesce(msd.completecode, -1) = 1 and
            exists (select 1
                    from mysmalldata msd2
                    where msd2.MFGORDNO = msd.MFGORDNO and
                          msd2.sequence = msd.sequence and
                          msd2.badge = msd.badge and
                          msd2.ttime = msd.ttime and
                          msd2.completecode is null
                   )
            )
           );   

Здесь - это дБ <> скрипка.

1 голос
/ 22 апреля 2019

Начал работать над моей собственной версией, подумал: «Нет, иди с @ Гордоном, и как он это сделал», решил некоторые проблемы с этим, поэтому взял (+1) и немного изменил его:

SELECT msd.*
 from mysmalldata msd
 where msd.completecode = 0  --  All "completeCode=0" rows are accepted
  or (--  All "NULL" rows for which there is no matching "completeCode=1" row are accepted
      msd.completecode is null
       and not exists (select 1
                        from mysmalldata msd2
                         where msd2.MFGORDNO = msd.MFGORDNO
                          and msd2.sequence = msd.sequence
                          and msd2.badge = msd.badge
                          and msd2.ttime = msd.ttime
                          and msd2.completecode = 1
                      )
     )
 --  Note that no "completeCode=1" rows are accepted
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...