Oracle
 sql >> база данни >  >> RDS >> Oracle

oracle Изберете дати за артикули, продадени в рамките на 1 минута един от друг

Можете да използвате LAG /LEAD аналитични функции за сравняване на предишния и следващия ред, за да се определи дали са в рамките на минута от текущия ред:

SELECT location,
       LISTAGG( equipment_type, ',' )
         WITHIN GROUP ( ORDER BY sold_date )
         AS equipment_types,
       LISTAGG( TO_CHAR( sold_date, 'HH24:MI:SS' ), ',' )
         WITHIN GROUP ( ORDER BY sold_date )
         AS sold_dates
FROM   (
  SELECT num_cars,
         equipment_type,
         location,
         sold_date,
         CASE
         WHEN within_minute_of_prev = 1 OR within_minute_of_next = 1
         THEN SUM(
                CASE
                WHEN within_minute_of_prev = 0 AND within_minute_of_next = 1
                THEN 1
                ELSE 0
                END
              ) OVER ( PARTITION BY location ORDER BY sold_date )
         END AS grp
  FROM   (
    SELECT c.*,
           CASE
           WHEN ( sold_date
                  - LAG( sold_date ) OVER ( PARTITION BY location ORDER BY sold_date )
                ) DAY TO SECOND
                <= INTERVAL '1' MINUTE
           THEN 1
           ELSE 0
           END AS within_minute_of_prev,
           CASE
           WHEN ( LEAD( sold_date ) OVER ( PARTITION BY location ORDER BY sold_date )
                  - sold_date
                ) DAY TO SECOND
                <= INTERVAL '1' MINUTE
           THEN 1
           ELSE 0
           END AS within_minute_of_next
    FROM   car_sales c
  )
)
WHERE grp IS NOT NULL
GROUP BY location, grp;

Което за вашите примерни данни:

CREATE TABLE CAR_SALES ( NUM_CARS, EQUIPMENT_TYPE, LOCATION, SOLD_DATE ) AS
  SELECT   8, 'Rovers',   'coventry',   DATE '2019-09-07' + INTERVAL '10:00:12' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   1, 'Rovers',   'coventry',   DATE '2019-09-07' + INTERVAL '10:00:45' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   9, 'Jaguars',  'coventry',   DATE '2019-09-07' + INTERVAL '06:00:00' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   7, 'Rovers',   'leamington', DATE '2019-08-30' + INTERVAL '13:10:13' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT  10, 'Trans Am', 'leamington', DATE '2019-08-30' + INTERVAL '09:00:00' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   2, 'Trans Am', 'leamington', DATE '2019-08-30' + INTERVAL '13:10:48' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   8, 'Rovers',   'coventry',   DATE '2019-09-06' + INTERVAL '18:00:00' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   4, 'Rovers',   'leamington', DATE '2019-09-06' + INTERVAL '09:00:00' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT 100, 'Trans Am', 'leamington', DATE '2019-09-06' + INTERVAL '08:59:45' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   1, 'corvette', 'leamington', DATE '2019-09-06' + INTERVAL '09:00:10' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   2, 'Toyota',   'coventry',   DATE '2019-09-06' + INTERVAL '10:00:00' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT  15, 'Rovers',   'coventry',   DATE '2019-09-07' + INTERVAL '11:05:00' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   2, 'Jaguars',  'coventry',   DATE '2019-09-07' + INTERVAL '17:02:07' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   3, 'Trans Am', 'leamington', DATE '2019-08-30' + INTERVAL '13:10:25' HOUR TO SECOND FROM DUAL;

Изходи:

db<>fiddle тук

Актуализация

Много по-кратка заявка на Oracle 12c използва MATCH_RECOGNIZE :

SELECT location,
       LISTAGG( equipment_type, ',' )
         WITHIN GROUP ( ORDER BY sold_date )
         AS equipment_types,
       LISTAGG( TO_CHAR( sold_date, 'HH24:MI:SS' ), ',' )
         WITHIN GROUP ( ORDER BY sold_date )
         AS sold_times
FROM   car_sales
MATCH_RECOGNIZE (
   PARTITION BY location
   ORDER BY sold_date
   MEASURES  
      MATCH_NUMBER() AS mno
   ALL ROWS PER MATCH
   PATTERN (A B+)
   DEFINE
      B AS B.sold_date <= PREV(B.sold_date) + interval '1' minute
)
GROUP BY location, mno
ORDER BY location, mno;

Което за тестовите данни:

CREATE TABLE CAR_SALES ( NUM_CARS, EQUIPMENT_TYPE, LOCATION, SOLD_DATE ) AS
  SELECT   8, 'Rovers',   'coventry',   DATE '2019-09-07' + INTERVAL '10:00:12' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   1, 'Rovers',   'coventry',   DATE '2019-09-07' + INTERVAL '10:00:45' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   3, 'Rovers',   'coventry',   DATE '2019-09-07' + INTERVAL '10:01:15' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   3, 'Rovers',   'coventry',   DATE '2019-09-07' + INTERVAL '10:01:30' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   9, 'Jaguars',  'coventry',   DATE '2019-09-07' + INTERVAL '06:00:00' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   7, 'Rovers',   'leamington', DATE '2019-08-30' + INTERVAL '13:10:13' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT  10, 'Trans Am', 'leamington', DATE '2019-08-30' + INTERVAL '09:00:00' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   2, 'Trans Am', 'leamington', DATE '2019-08-30' + INTERVAL '13:10:48' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   8, 'Rovers',   'coventry',   DATE '2019-09-06' + INTERVAL '18:00:00' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   4, 'Rovers',   'leamington', DATE '2019-09-06' + INTERVAL '09:00:00' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT 100, 'Trans Am', 'leamington', DATE '2019-09-06' + INTERVAL '08:59:45' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   1, 'corvette', 'leamington', DATE '2019-09-06' + INTERVAL '09:00:10' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   2, 'Toyota',   'coventry',   DATE '2019-09-06' + INTERVAL '10:00:00' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT  15, 'Rovers',   'coventry',   DATE '2019-09-07' + INTERVAL '11:05:00' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   2, 'Jaguars',  'coventry',   DATE '2019-09-07' + INTERVAL '17:02:07' HOUR TO SECOND FROM DUAL UNION ALL
  SELECT   3, 'Trans Am', 'leamington', DATE '2019-08-30' + INTERVAL '13:10:25' HOUR TO SECOND FROM DUAL;

Изходи:

db<>fiddle тук



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Курсор за цикъл в Oracle

  2. SQL заявка за намиране на редове с поне една от посочените стойности

  3. Продължавам да получавам грешка до върнатия VARCHAR(4)

  4. Каква дължина може да има името на мрежовия интерфейс?

  5. колони в Oracle Pivot