Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Oracle SQL - Xác định phạm vi giá trị tuần tự

Điều này rất dễ thực hiện với một kỹ thuật có tên là Tabibitosan.

Những gì kỹ thuật này thực hiện là so sánh vị trí của các hàng trong nhóm với tập hợp các hàng tổng thể, để tìm ra liệu các hàng trong cùng một nhóm có cạnh nhau hay không.

Ví dụ:với dữ liệu mẫu của bạn, nó trông giống như sau:

WITH your_table AS (SELECT 1 ID, 'Michael' NAME, 'Marketing' department FROM dual UNION ALL
                    SELECT 2 ID, 'Alex' NAME, 'Marketing' department FROM dual UNION ALL
                    SELECT 3 ID, 'Tom' NAME, 'Marketing' department FROM dual UNION ALL
                    SELECT 4 ID, 'John' NAME, 'Sales' department FROM dual UNION ALL
                    SELECT 5 ID, 'Brad' NAME, 'Marketing' department FROM dual UNION ALL
                    SELECT 6 ID, 'Leo' NAME, 'Marketing' department FROM dual UNION ALL
                    SELECT 7 ID, 'Kevin' NAME, 'Production' department FROM dual)
-- end of mimicking your table with data in it. See the SQL below:
SELECT ID,
       NAME,
       department,
       row_number() OVER (ORDER BY ID) overall_rn,
       row_number() OVER (PARTITION BY department ORDER BY ID) department_rn,
       row_number() OVER (ORDER BY ID) - row_number() OVER (PARTITION BY department ORDER BY ID) grp
FROM   your_table;

        ID NAME    DEPARTMENT OVERALL_RN DEPARTMENT_RN        GRP
---------- ------- ---------- ---------- ------------- ----------
         1 Michael Marketing           1             1          0
         2 Alex    Marketing           2             2          0
         3 Tom     Marketing           3             3          0
         4 John    Sales               4             1          3
         5 Brad    Marketing           5             4          1
         6 Leo     Marketing           6             5          1
         7 Kevin   Production          7             1          6

Ở đây, tôi đã cung cấp cho tất cả các hàng trên toàn bộ tập dữ liệu một số hàng theo thứ tự id tăng dần (overall_rn ), và tôi đã cung cấp cho các hàng trong mỗi bộ phận một số hàng (department_rn cột), lại theo thứ tự id tăng dần.

Bây giờ tôi đã làm điều đó, chúng ta có thể trừ một cái cho cái kia (grp cột).

Lưu ý rằng số trong cột grp vẫn giữ nguyên như thế nào đối với các hàng mô tả cạnh nhau, nhưng nó thay đổi mỗi khi có khoảng trống.

Ví dụ. đối với bộ phận Tiếp thị, hàng 1-3 nằm cạnh nhau và có grp =0, nhưng hàng Tiếp thị thứ 4 thực sự nằm trên hàng thứ 5 của tập kết quả tổng thể, vì vậy nó hiện có số grp khác. Vì hàng tiếp thị thứ 5 nằm trên hàng thứ 6 của tập hợp tổng thể, nó có cùng số grp với hàng tiếp thị thứ 4, vì vậy chúng tôi biết chúng ở cạnh nhau.

Khi chúng tôi có thông tin grp đó, việc đơn giản là thực hiện nhóm truy vấn tổng hợp trên cả bộ phận và cột grp mới của chúng tôi, sử dụng min và max để tìm id đầu và cuối:

WITH your_table AS (SELECT 1 ID, 'Michael' NAME, 'Marketing' department FROM dual UNION ALL
                    SELECT 2 ID, 'Alex' NAME, 'Marketing' department FROM dual UNION ALL
                    SELECT 3 ID, 'Tom' NAME, 'Marketing' department FROM dual UNION ALL
                    SELECT 4 ID, 'John' NAME, 'Sales' department FROM dual UNION ALL
                    SELECT 5 ID, 'Brad' NAME, 'Marketing' department FROM dual UNION ALL
                    SELECT 6 ID, 'Leo' NAME, 'Marketing' department FROM dual UNION ALL
                    SELECT 7 ID, 'Kevin' NAME, 'Production' department FROM dual)
-- end of mimicking your table with data in it. See the SQL below:
SELECT department,
       MIN(ID) start_id,
       MAX(ID) end_id
FROM   (SELECT ID,
               NAME,
               department,
               row_number() OVER (ORDER BY ID) - row_number() OVER (PARTITION BY department ORDER BY ID) grp
        FROM   your_table)
GROUP BY department, grp;

DEPARTMENT   START_ID     END_ID
---------- ---------- ----------
Marketing           1          3
Marketing           5          6
Sales               4          4
Production          7          7

N.B., tôi đã cho rằng khoảng trống trong các cột id không quan trọng (tức là nếu không có hàng nào cho id =6 (vì vậy id của Leo và Kevin lần lượt là 7 và 8), thì Leo và Brad sẽ vẫn xuất hiện trong cùng một nhóm, với id bắt đầu =5 và id kết thúc =7.

Nếu khoảng trống trong các cột id được coi là biểu thị một nhóm mới, thì bạn chỉ có thể sử dụng id để gắn nhãn cho tập hợp các hàng tổng thể (tức là không cần tính tổng thể_rn; chỉ cần sử dụng cột id thay thế).

Điều đó có nghĩa là truy vấn của bạn sẽ trở thành:

WITH your_table AS (SELECT 1 ID, 'Michael' NAME, 'Marketing' department FROM dual UNION ALL
                    SELECT 2 ID, 'Alex' NAME, 'Marketing' department FROM dual UNION ALL
                    SELECT 3 ID, 'Tom' NAME, 'Marketing' department FROM dual UNION ALL
                    SELECT 4 ID, 'John' NAME, 'Sales' department FROM dual UNION ALL
                    SELECT 5 ID, 'Brad' NAME, 'Marketing' department FROM dual UNION ALL
                    SELECT 7 ID, 'Leo' NAME, 'Marketing' department FROM dual UNION ALL
                    SELECT 8 ID, 'Kevin' NAME, 'Production' department FROM dual)
-- end of mimicking your table with data in it. See the SQL below:
SELECT department,
       MIN(ID) start_id,
       MAX(ID) end_id
FROM   (SELECT ID,
               NAME,
               department,
               ID - row_number() OVER (PARTITION BY department ORDER BY ID) grp
        FROM   your_table)
GROUP BY department, grp;

DEPARTMENT   START_ID     END_ID
---------- ---------- ----------
Marketing           1          3
Sales               4          4
Marketing           5          5
Marketing           7          7
Production          8          8


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm thế nào để chỉnh sửa thủ tục đã lưu trong Oracle SQL Developer?

  2. Cách khôi phục bản vá sau giai đoạn chuyển đổi không thành công trong R12.2

  3. Có cách nào để buộc OracleCommand.BindByName trở thành true theo mặc định cho ODP.NET không?

  4. Cách cài đặt SQLcl trên máy Mac

  5. Làm thế nào để tạo hàm trong PL / SQL?