SQL的默认行
数据库-甲骨文SQL的默认行,sql,oracle,Sql,Oracle,数据库-甲骨文 create table customer_exercise( customer_id number, exercise_id number, cnt number, exercise_date date) 资料 当in子句中的条件不存在记录时,是否可以获取默认行 select customer_id, exercise_id, sum(cnt) from customer_exercise where customer_id in (1000, 1001, 1003)
create table customer_exercise(
customer_id number,
exercise_id number,
cnt number,
exercise_date date)
资料
当in子句中的条件不存在记录时,是否可以获取默认行
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)
上述查询的结果-
1000 20 2
1000 10 3
1001 20 6
由于in子句中的客户ID可能没有特定练习ID的记录,因此是否可以使用SQL获得如下结果,这些结果的总和为0?例如,1001没有练习id=10的记录,因此总和为0
1001 10 0
1003 10 0
1003 20 0
1000 20 2
1000 10 3
1001 20 6
您可以使用:
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;
当然,您有多个选项可以在cte内部生成
交叉连接
:
- 硬编码值
- 临时桌
- 子查询
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;
当然,您有多个选项可以在cte内部生成
交叉连接
:
- 硬编码值
- 临时桌
- 子查询
条件转换为集合(如a),将它们扩展为CTE中的关系数据,然后交叉连接它们;并左键连接到实际表以查看匹配项:
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.
如果您已经有单独的customer
和exercise
表,并且它们至少包含您要查找的所有ID,那么您可以直接使用这些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
通过这种方式,您将无法获得客户和练习表中不存在的任何ID的默认行,但这可能不是问题。您可以将中的子句条件转换为集合(如a),将它们扩展为CTE中的关系数据,然后交叉连接它们;并左键连接到实际表以查看匹配项:
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.
如果您已经有单独的customer
和exercise
表,并且它们至少包含您要查找的所有ID,那么您可以直接使用这些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
通过这种方式,您不会获得customer
和exercise
表中不存在的任何ID的默认行,但这可能不是问题。使用coalesce(sum(cnt),0)是否有其他表列出所有客户ID和exercise ID?是的,customer\u exercise是一个多映射表。有一个包含客户信息和练习信息的客户表和练习表。您的示例数据的id为1000和1001,但预期结果还包括id 1002和1003。为什么?使用coalesce(sum(cnt),0)您是否有其他表列出所有客户ID和练习ID?是的,customer_练习是一个多映射表。有一个包含客户信息和练习信息的客户表和练习表。您的示例数据的id为1000和1001,但预期结果还包括id 1002和1003。怎么了?非常感谢非常感谢