甲骨文的CTE问题

问题描述 投票:0回答:1

我已经实施了你的修改,并试图再做一些修改。我的目标是对access_history表进行更新,并为这些记录设置 processed = 1,从而创建一组emp_attendance记录。

当我尝试查找MIN(ts)和MAX(ts)时,我得到了以下错误信息

ORA-00937:不是单组群功能。

当我通过添加一个组时,我得到了一个不同的错误。我发布了带有错误的代码,我想知道你是否可以告诉我如何完成删除错误并在同一个查询中发布更新。

-- Drop table emp_info purge:
-- Drop table locations purge;
-- Drop table access_histoty purge;
-- Drop table emp_attendance purge;

ALTER SESSION SET NLS_DATE_FORMAT = 'MMDDYYYY HH24:MI:SS';

CREATE TABLE employees
(
   employee_id NUMBER(6),
   first_name VARCHAR2(20),
   last_name VARCHAR2(25) NOT NULL,
   card_num varchar2(10)  NOT NULL
);

ALTER TABLE employees
     ADD ( CONSTRAINT employee_id_pk
   PRIMARY KEY (employee_id));


Insert into employees values (1, 'Mike', 'Jones', 'AAA1');

Insert into employees values (2, 'Jane', 'Doe', 'BBB2');


Insert into employees values (3, 'Paul', 'Smith', 'CCC3');

Insert into employees values (4, 'John', 'Henry', 'DDD4');



 Create table locations(
   location_id NUMBER(4),
   location_name varchar2(30),
   location_type char(1));

 -- A=access T=Time & Attendance 

ALTER TABLE locations 
     ADD ( CONSTRAINT lication_id_pk
   PRIMARY KEY (location_id));



Insert into locations values (101, 'South Front Door 1', 'T');

  Insert into locations values (102, 'South Front Door 2', 'T');

  Insert into locations values (103, 'East Back Door 1', 'T');

   Insert into locations values (104, 'East Back Door 2', 'T');

   Insert into locations values (105,'Computer Room', 'A');

   Insert into locations values (106,'1st Floor North',  'A');


Create table access_history(
   employee_id NUMBER(6), 
   card_num varchar2(10),
   location_id number(4),
   Access_date date,
   ts timestamp default systimestamp,
   processed NUMBER(1) default 0
);


INSERT INTO access_history
( employee_id, card_num,
   location_id, Access_date )
 VALUES (1, 'AAA1', 101,    TO_DATE('06212020 21:02:04',  'MMDDYYYY HH24:MI:SS'));


   -- TYpe T no previous data for this
   -- empid record INSERT empid, 
    -- start  time ONLY in table below 
     -- and  update last_start_date  
     -- with DATETIME.



INSERT INTO access_history
( employee_id, card_num,
   location_id, Access_date )
 VALUES (1, 'AAA1', 102,    TO_DATE('06212020 23:52:14',  'MMDDYYYY HH24:MI:SS'));


  -- Type T record empid, start_time
  --  set update end_time only in
  -- emp_attendance.



INSERT INTO access_history
( employee_id, card_num,
   location_id, Access_date )
 VALUES (2, 'BBB2', 103,    TO_DATE('06212020 08:32:35',  'MMDDYYYY HH24:MI:SS'));


 -- TYpe T  INSERT empid, start 
 -- time ONLY in emp_attendance.  
 -- update last_start_date with 
 --  DATETIME on emp_info table



INSERT INTO access_history
( employee_id, card_num,
   location_id, Access_date )
 VALUES (2, 'BBB2', 102,    TO_DATE('06212020 15:39:05',  'MMDDYYYY HH24:MI:SS'));


-- Type T record empid, start_time 
--  set, update end_time only in
-- emp_attendance.


INSERT INTO access_history
( employee_id, card_num,
   location_id, Access_date )
 VALUES (3, 'CCC3', 103,    TO_DATE('06212020 15:39:05',  'MMDDYYYY HH24:MI:SS'));


 -- TYpe T  INSERT empid, start 
 -- time ONLY in emp_attendance.  
 -- update last_start_date with 
 --  DATETIME on emp_info table



INSERT INTO access_history
( employee_id, card_num,
   location_id, Access_date )
 VALUES (3, 'CCC3', 105,    TO_DATE('06212020 18:19:55',  'MMDDYYYY HH24:MI:SS'));


-- Type A record don't do anything to 
-- emp_attendance.



INSERT INTO access_history
( employee_id, card_num,
   location_id, Access_date )
 VALUES (4, 'DDD4', 102,    TO_DATE('06212020 08:49:35',  'MMDDYYYY HH24:MI:SS'));

--  single record with no pair. Set
-- end_date to start_date if end_date
-- is NULL



INSERT INTO access_history
( employee_id, card_num,
   location_id, Access_date )
 VALUES (3, 'CCC3', 104,    TO_DATE('06222020 04:04:35',  'MMDDYYYY HH24:MI:SS'));


-- Type T record empid, start_time 
--  set, update end_time only in
-- emp_attendance.


 CREATE TABLE  emp_attendance    
  (seq_num NUMBER(10),
   employee_id NUMBER(6),
   start_date DATE,
   end_date DATE,
   create_date DATE DEFAULT SYSDATE
   );

   Create sequence emp_attendance_seq;

   insert into emp_attendance.   
     (seq_num, 
       employee_id, 
       start_date, 
      end_date)

   with

   -- error capturing min,max ts
   --
   prep (min_ts, max_ts, employee_id, start_date, rn, end_date) as (

     select MIN(ts), MAX(ts), employee_id, access_date

        , row_number()      over (partition by card_num order by access_date)

      , lead(access_date) over (partition by card_num order by access_date)

   from   access_history

 where  location_id in ( select location_id

                     from   locations

                      where  location_type = 'T'

                  )

                  AND processed = 0

  )

   select emp_attendance_seq.nextval,

      employee_id,

     start_date,

   nvl(end_date, start_date)

  from prep

 where  mod(rn, 2) = 1;
sql oracle syntax common-table-expression
1个回答
1
投票

在下面的CTE中,我试图将记录从SELECT中INSERT到表emp_attendance中,但我似乎无法工作。

如果你描述一下你的尝试有什么问题,会更容易帮助你。因为,它的方式是,它只是缺乏的 INSERT INTO 语句、序列调用和 NVL 函数--至少,我是这么理解的。

SQL> insert into emp_attendance (seq_num, employee_id, start_date, end_Date)
  2  with
  3    prep (employee_id, start_date, rn, end_date) as (
  4      select employee_id, access_date
  5           , row_number()      over (partition by card_num order by access_date)
  6           , lead(access_date) over (partition by card_num order by access_date)
  7      from   access_history
  8      where  location_id in ( select location_id
  9                          from   locations
 10                          where  location_type = 'T'
 11                        )
 12    )
 13  select emp_attendance_seq.nextval,
 14         employee_id,
 15         start_date,
 16         nvl(end_date, start_date)
 17  from prep
 18  where  mod(rn, 2) = 1;

4 rows created.

SQL> select * From emp_attendance;

   SEQ_NUM EMPLOYEE_ID START_DATE          END_DATE
---------- ----------- ------------------- -------------------
         1           1 21.06.2020 21:02:04 21.06.2020 23:52:14
         2           2 21.06.2020 08:32:35 21.06.2020 15:39:05
         3           3 21.06.2020 15:39:05 22.06.2020 04:04:35
         4           4 21.06.2020 08:49:35 21.06.2020 08:49:35

SQL>
© www.soinside.com 2019 - 2024. All rights reserved.