Oracle SQL 根据订单id统计客户最近10天的订单
Oracle SQL Count orders by customers in the last 10 days based on order id
在 Oracle SQL 中,我的目标是接收客户在过去 10 天内发出的订单总数,但显示的是订单 ID 而不是客户 ID。
给出以下情况:
我想要的结果是:
我怎样才能以最有效的方式促进这一点?
你可以尝试用self-join带日期的减法条件,条件需要判断10天内有哪些行
查询 1:
SELECT t1.Customer_ID,
t1.Order_NR,
COUNT(*) Number_Orders
FROM T t1
INNER JOIN T t2
ON t1.Customer_ID = t2.Customer_ID AND t2.Order_Date BETWEEN t1.Order_Date - 10 AND t1.Order_Date
GROUP BY t1.Customer_ID,
t1.Order_NR
ORDER BY t1.Order_NR
| CUSTOMER_ID | ORDER_NR | NUMBER_ORDERS |
|-------------|----------|---------------|
| 100 | 1 | 1 |
| 200 | 2 | 1 |
| 300 | 3 | 1 |
| 100 | 4 | 2 |
| 100 | 5 | 2 |
| 200 | 6 | 1 |
| 700 | 7 | 1 |
| 800 | 8 | 2 |
| 800 | 9 | 2 |
| 800 | 10 | 3 |
您不需要 self-join,只需使用 COUNT
分析函数和 RANGE
window:
SELECT customer_id,
order_no,
order_date,
COUNT(*) OVER (
PARTITION BY customer_id
ORDER BY order_date
RANGE BETWEEN INTERVAL '10' DAY PRECEDING AND INTERVAL '0' DAY FOLLOWING
) AS numer_orders
FROM table_name
ORDER BY order_no
其中,对于示例数据:
CREATE TABLE table_name (customer_id, order_no, order_date) AS
SELECT 100, 1, DATE '2021-01-01' FROM DUAL UNION ALL
SELECT 200, 2, DATE '2021-01-02' FROM DUAL UNION ALL
SELECT 300, 3, DATE '2021-01-05' FROM DUAL UNION ALL
SELECT 100, 4, DATE '2021-01-09' FROM DUAL UNION ALL
SELECT 100, 5, DATE '2021-01-15' FROM DUAL UNION ALL
SELECT 200, 6, DATE '2021-01-18' FROM DUAL UNION ALL
SELECT 700, 7, DATE '2021-01-20' FROM DUAL UNION ALL
SELECT 800, 8, DATE '2021-01-25' FROM DUAL UNION ALL
SELECT 800, 9, DATE '2021-01-25' FROM DUAL UNION ALL
SELECT 800, 10, DATE '2021-01-28' FROM DUAL;
输出:
CUSTOMER_ID
ORDER_NO
ORDER_DATE
NUMER_ORDERS
100
1
01-JAN-21
1
200
2
02-JAN-21
1
300
3
05-JAN-21
1
100
4
09-JAN-21
2
100
5
15-JAN-21
2
200
6
18-JAN-21
1
700
7
20-JAN-21
1
800
8
25-JAN-21
2
800
9
25-JAN-21
2
800
10
28-JAN-21
3
db<>fiddle here
在 Oracle SQL 中,我的目标是接收客户在过去 10 天内发出的订单总数,但显示的是订单 ID 而不是客户 ID。
给出以下情况:
我想要的结果是:
我怎样才能以最有效的方式促进这一点?
你可以尝试用self-join带日期的减法条件,条件需要判断10天内有哪些行
查询 1:
SELECT t1.Customer_ID,
t1.Order_NR,
COUNT(*) Number_Orders
FROM T t1
INNER JOIN T t2
ON t1.Customer_ID = t2.Customer_ID AND t2.Order_Date BETWEEN t1.Order_Date - 10 AND t1.Order_Date
GROUP BY t1.Customer_ID,
t1.Order_NR
ORDER BY t1.Order_NR
| CUSTOMER_ID | ORDER_NR | NUMBER_ORDERS |
|-------------|----------|---------------|
| 100 | 1 | 1 |
| 200 | 2 | 1 |
| 300 | 3 | 1 |
| 100 | 4 | 2 |
| 100 | 5 | 2 |
| 200 | 6 | 1 |
| 700 | 7 | 1 |
| 800 | 8 | 2 |
| 800 | 9 | 2 |
| 800 | 10 | 3 |
您不需要 self-join,只需使用 COUNT
分析函数和 RANGE
window:
SELECT customer_id,
order_no,
order_date,
COUNT(*) OVER (
PARTITION BY customer_id
ORDER BY order_date
RANGE BETWEEN INTERVAL '10' DAY PRECEDING AND INTERVAL '0' DAY FOLLOWING
) AS numer_orders
FROM table_name
ORDER BY order_no
其中,对于示例数据:
CREATE TABLE table_name (customer_id, order_no, order_date) AS
SELECT 100, 1, DATE '2021-01-01' FROM DUAL UNION ALL
SELECT 200, 2, DATE '2021-01-02' FROM DUAL UNION ALL
SELECT 300, 3, DATE '2021-01-05' FROM DUAL UNION ALL
SELECT 100, 4, DATE '2021-01-09' FROM DUAL UNION ALL
SELECT 100, 5, DATE '2021-01-15' FROM DUAL UNION ALL
SELECT 200, 6, DATE '2021-01-18' FROM DUAL UNION ALL
SELECT 700, 7, DATE '2021-01-20' FROM DUAL UNION ALL
SELECT 800, 8, DATE '2021-01-25' FROM DUAL UNION ALL
SELECT 800, 9, DATE '2021-01-25' FROM DUAL UNION ALL
SELECT 800, 10, DATE '2021-01-28' FROM DUAL;
输出:
CUSTOMER_ID ORDER_NO ORDER_DATE NUMER_ORDERS 100 1 01-JAN-21 1 200 2 02-JAN-21 1 300 3 05-JAN-21 1 100 4 09-JAN-21 2 100 5 15-JAN-21 2 200 6 18-JAN-21 1 700 7 20-JAN-21 1 800 8 25-JAN-21 2 800 9 25-JAN-21 2 800 10 28-JAN-21 3
db<>fiddle here