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

Cách tạo hàng cho phạm vi ngày theo khóa

trong 10g / 11g, bạn có thể sử dụng mệnh đề mô hình cho việc này.

SQL> with emps as (select rownum id, name, start_date,
  2                       end_date, trunc(end_date)-trunc(start_date) date_range
  3                  from table1)
  4  select name, the_date
  5    from emps
  6  model partition by(id as key)
  7        dimension by(0 as f)
  8        measures(name, start_date, cast(null as date) the_date, date_range)
  9        rules (the_date [for f from 0 to date_range[0] increment 1]  = start_date[0] + cv(f),
 10               name[any] = name[0]);

NAME        THE_DATE
----------- ----------
DAVID SMITH 01-01-2001
DAVID SMITH 01-02-2001
DAVID SMITH 01-03-2001
DAVID SMITH 01-04-2001
DAVID SMITH 01-05-2001
DAVID SMITH 01-06-2001
JOHN SMITH  02-07-2012
JOHN SMITH  02-08-2012
JOHN SMITH  02-09-2012

9 rows selected.

tức là truy vấn cơ sở của bạn:

select rownum id, name, start_date,
       end_date, trunc(end_date)-trunc(start_date) date_range
  from table1

chỉ cần xác định ngày + phạm vi (Tôi đã sử dụng id rownum, nhưng nếu bạn có PK, bạn có thể sử dụng nó để thay thế.

phân vùng phân chia các phép tính của chúng tôi cho mỗi ID (hàng duy nhất):

6  model partition by(id as key)

các biện pháp:

8        measures(name, start_date, cast(null as date) the_date, date_range)

xác định các thuộc tính mà chúng ta sẽ xuất / tính toán. trong trường hợp này, chúng tôi đang làm việc với tên và ngày bắt đầu cộng với phạm vi hàng cần tạo. ngoài ra, tôi đã xác định một cột the_date điều đó sẽ giữ ngày được tính toán (tức là chúng tôi muốn tính toán start_date + n trong đó n là từ 0 đến phạm vi.

các quy tắc xác định CÁCH chúng ta sẽ điền các cột của mình:

9        rules (the_date [for f from 0 to date_range[0] increment 1]  = start_date[0] + cv(f),
10               name[any] = name[0]);

vậy với

the_date [for f from 0 to date_range[0] increment 1]

chúng tôi đang nói rằng chúng tôi sẽ tạo ra số hàng mà date_range giữ + 1 (tức là tổng cộng 6 ngày). giá trị của f có thể được tham chiếu thông qua cv (giá trị hiện tại).

vì vậy trên hàng 1 cho david, chúng ta sẽ có the_date [0] = start_date+0 và sau đó ở hàng 2, chúng ta sẽ có the_date [1] = start_date+1 . tất cả các cách tính đến start_date + 5 (tức là end_date )

p.s.for kết nối bằng cách bạn cần làm điều gì đó như sau:

select 
    A.EMPLOYEE_NAME,
    A.START_DATE+(b.r-1) AS INDIVIDUAL_DAY,
    TO_CHAR(A.START_DATE,'MM/DD/YYYY') START_DATE,
    TO_CHAR(A.END_DATE,'MM/DD/YYYY') END_DATE
FROM table1 A
     cross join (select rownum r
                   from (select max(end_date-start_date) d from table1)
                  connect by level-1 <= d) b
 where A.START_DATE+(b.r-1) <= A.END_DATE
 order by 1, 2;

tức là cô lập kết nối bằng một truy vấn con, sau đó lọc ra các hàng có cá nhân_ngày> ngày.

nhưng tôi KHÔNG NÊN giới thiệu cách tiếp cận này. hiệu suất của nó sẽ kém hơn so với cách tiếp cận mô hình (đặc biệt nếu phạm vi trở nên lớn hơn).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nếu dữ liệu tồn tại, khác ... sử dụng Oracle SQL?

  2. Làm thế nào để viết / cập nhật Oracle blob một cách đáng tin cậy?

  3. Thả các phân vùng cũ hơn 2 tháng

  4. Số hàng tăng dần trên nhóm có các nhóm lặp lại

  5. thay đổi cột thả bảng trong cơ sở dữ liệu oracle