2017-08-14 30 views
0

DB - 甲骨文默認行的SQL

create table customer_exercise(
customer_id number, 
exercise_id number, 
cnt number, 
exercise_date date) 

數據

1000 10 3 14-AUG-17 
1001 20 6 14-AUG-17 
1000 20 2 14-AUG-17 

是否有可能當記錄不爲條件條款存在獲得默認行?上述查詢 -

1000 20 2 
1000 10 3 
1001 20 6 

由於客戶IDS的條款可能沒有某些運動ID的記錄,是否有可能使用SQL得到像一個結果

select customer_id, exercise_id, sum(cnt) 
from customer_exercise 
where customer_id in (1000, 1001, 1003) 
    and exercise_id in (10, 20) 
group by customer_id, exercise_id 
order by sum(cnt) 

結果以下總和爲0爲那些?對於例如1001不具備運動的id = 10的記錄,所以總和爲0。

1001 10 0 
1003 10 0 
1003 20 0 
1000 20 2 
1000 10 3 
1001 20 6 
+0

使用coalesce(sum(cnt),0) –

+0

您是否有其他表格列出所有客戶ID和鍛鍊ID? –

+0

是的,customer_exercise是一個多對多的映射表。有客戶表和鍛鍊表與客戶信息和鍛鍊信息。 – rayne

回答

1

你可以把你的in子句條件到集合(如built-in collection type, handy for this sort of thing),擴大它們變成關係型數據的熱膨脹係數,然後跨加入他們的行列;和左連接到真正的表,看看有什麼相匹配:

with customer_cte (customer_id) as (
    select * from table(sys.odcinumberlist(1000, 1001, 1003)) 
), 
exercise_cte (exercise_id) as (
    select * from table(sys.odcinumberlist(10, 20)) 
) 
select c.customer_id, e.exercise_id, coalesce(sum(ce.cnt), 0) as total_cnt 
from customer_cte c 
cross join exercise_cte e 
left join customer_exercise ce 
on ce.customer_id = c.customer_id 
and ce.exercise_id = e.exercise_id 
group by c.customer_id, e.exercise_id 
order by coalesce(sum(cnt), 0), customer_id, exercise_id 
/

CUSTOMER_ID EXERCISE_ID TOTAL_CNT 
----------- ----------- ---------- 
     1001   10   0 
     1003   10   0 
     1003   20   0 
     1000   20   2 
     1000   10   3 
     1001   20   6 

6 rows selected. 

如果你已經這樣做有單獨的customerexercise表,它們至少包含所有你要找的ID,那麼你可以使用這些而不是直接和過濾器對他們,而不是你的映射表:

select c.customer_id, e.exercise_id, coalesce(sum(ce.cnt), 0) as total_cnt 
from customer c 
cross join exercise e 
left join customer_exercise ce 
on ce.customer_id = c.customer_id 
and ce.exercise_id = e.exercise_id 
where c.customer_id in (1000, 1001, 1003) 
and e.exercise_id in (10, 20) 
group by c.customer_id, e.exercise_id 
order by coalesce(sum(cnt), 0), customer_id, exercise_id 

你不會得到默認的行爲沒有在customerexercise表這種方式存在的任何標識,但是這可能不是一個問題。

+0

非常感謝 – rayne

2

你可以使用:

WITH cte AS (
    SELECT * 
    FROM (SELECT 1000 AS customer_id FROM DUAL UNION 
     SELECT 1001 FROM DUAL UNION 
     SELECT 1003 FROM DUAL) s 
    CROSS JOIN (SELECT 10 AS exercise_id FROM DUAL UNION 
       SELECT 20 FROM DUAL) s2 
) 
SELECT c.customer_id , c.exercise_id, COALESCE(sum(ce.cnt),0) AS s 
FROM cte c 
LEFT JOIN customer_exercise ce 
    ON c.customer_id = ce.customer_id 
AND c.exercise_id = ce.exercise_id 
GROUP BY c.customer_id, c.exercise_id 
ORDER BY s; 

DB Fiddle Demo


當然你有多種選項可以在cte內生成CROSS JOIN

  • 硬編碼值
  • 臨時表
  • 子查詢