一次偶然的机会,使用到了万年不用的交叉连接(CROSS JOIN)
业务场景如下:
1、存在多个运营商,每个运营商下面都有各种类型的设备,不同运营商的设备不完全相同;
2、任何设备有且仅有两种用途‘订购’、‘置换’
3、现在要统计发生了‘订购’、‘置换’操作运营商的订购数和置换数
思路:
先用交叉连接把所有存在订购和置换的运营商和设备组合查询出来(这里把运营商表和设备表交叉连接起来也是一样)
再过滤掉无数据的组合
各运营商各设备的订购数如图
各运营商各设备的置换数如图
统计结果如下
SQL如下(可直接运行)
WITH a AS(
SELECT 'o1' 运营商,'s1' 设备,'10' 订购数 FROM dual
UNION ALL
SELECT 'o1', 's2', '15' FROM dual
UNION ALL
SELECT 'o1', 's3', '20' FROM dual
UNION ALL
SELECT 'o2', 's1', '30' FROM dual
UNION ALL
SELECT 'o2', 's2', '35' FROM dual
),
b AS(
SELECT 'o1' 运营商,'s1' 设备,'10' 置换数 FROM dual
UNION ALL
SELECT 'o1', 's2', '15' FROM dual
UNION ALL
SELECT 'o2', 's4', '20' FROM dual
UNION ALL
SELECT 'o2', 's1', '30' FROM dual
UNION ALL
SELECT 'o4', 's2', '35' FROM dual
),
op AS(
SELECT a.运营商 FROM a
UNION
SELECT b.运营商 FROM b
),
sb AS(
SELECT a.设备 FROM a
UNION
SELECT b.设备 FROM b
),
opsb AS(
SELECT DISTINCT op.运营商,sb.设备 FROM op
CROSS JOIN sb)
SELECT opsb.运营商,opsb.设备,NVL(a.订购数,0) 订购数,NVL(b.置换数,0) 置换数
FROM opsb
LEFT JOIN a ON a.运营商 = opsb.运营商 AND a.设备 = opsb.设备
LEFT JOIN b ON b.运营商 = opsb.运营商 AND b.设备 = opsb.设备
WHERE 订购数 IS NOT NULL
OR 置换数 IS NOT NULL