使用與IGNORE NULLS
選項LAG
解析函數在你的範圍開始找以前的行,然後使用COUNT
分析功能與一系列窗口得到計數:
SQL Fiddle
的Oracle 11g R2架構設置:
CREATE TABLE table_name (rn, id) AS
SELECT 1, 'C20' FROM DUAL UNION ALL
SELECT 2, 'C21' FROM DUAL UNION ALL
SELECT 3, 'C25' FROM DUAL UNION ALL
SELECT 4, 'C25' FROM DUAL UNION ALL
SELECT 5, 'C25' FROM DUAL UNION ALL
SELECT 6, 'C25' FROM DUAL UNION ALL
SELECT 7, 'C25' FROM DUAL UNION ALL
SELECT 8, 'C21' FROM DUAL UNION ALL
SELECT 9, 'C23' FROM DUAL UNION ALL
SELECT 10, 'C20' FROM DUAL UNION ALL
SELECT 11, 'C21' FROM DUAL UNION ALL
SELECT 12, 'C25' FROM DUAL UNION ALL
SELECT 13, 'C25' FROM DUAL UNION ALL
SELECT 14, 'C25' FROM DUAL UNION ALL
SELECT 15, 'C22' FROM DUAL UNION ALL
SELECT 16, 'C21' FROM DUAL UNION ALL
SELECT 17, 'C20' FROM DUAL;
查詢1:
SELECT *
FROM (
SELECT t.*,
COUNT(CASE id WHEN 'C25' THEN 1 END)
OVER (ORDER BY rn
ROWS BETWEEN (rn - prev_rn) PRECEDING AND CURRENT ROW)
AS num_c25
FROM (
SELECT t.*,
LAG(CASE id WHEN 'C20' THEN rn END, 1, 1)
IGNORE NULLS OVER (ORDER BY rn) AS prev_rn
FROM table_name t
) t
)
WHERE id = 'C20'
Results:
| RN | ID | PREV_RN | NUM_C25 |
|----|-----|---------|---------|
| 1 | C20 | 1 | 0 |
| 10 | C20 | 1 | 5 |
| 17 | C20 | 10 | 3 |
另一種方法是使用分層查詢:
查詢2:
SELECT *
FROM (
SELECT t.*,
COUNT(CASE id WHEN 'C25' THEN 1 END) OVER (ORDER BY rn ROWS BETWEEN LEVEL - 1 PRECEDING AND CURRENT ROW) AS num_c25,
CONNECT_BY_ROOT rn AS start_rn,
CONNECT_BY_ISLEAF AS isleaf
FROM table_name t
START WITH id = 'C20'
CONNECT BY PRIOR rn + 1 = rn
AND id <> 'C20'
)
WHERE isleaf = 1
Results:
| RN | ID | NUM_C25 | START_RN | ISLEAF |
|----|-----|---------|----------|--------|
| 9 | C23 | 5 | 1 | 1 |
| 16 | C21 | 3 | 10 | 1 |
| 17 | C20 | 0 | 17 | 1 |
來源
2017-09-25 08:32:05
MT0
哪些Oracle數據庫版本?或者你真的認爲'[mysql]'?請注意數據庫標記:答案通常需要特定於某個特定數據庫產品的語法,這可能就是這種情況。 – APC