我有一张桌子,其中有不同的城市和价值观。我想按城市查找差距,所以有表格:
City Value
Helsinki 1
Helsinki 2
Helsinki 5
Kuopio 4
Kuopio 5
Joensuu 1
Joensuu 2
Joensuu 3
我想知道城市之间的差距在哪里
City Value
Helsinki 3
Helsinki 4
Kuopio 1
Kuopio 2
Kuopio 3
Joensuu 4
Joensuu 5
我知道我可以使用
select rownum from dual connect by level<= 6 minus select value from table
但我不知道如何按组进行操作。
答案 0 :(得分:2)
您可以使用分区外部联接,该联接比使用自联接和CROSS JOIN
更有效:
Oracle设置:
CREATE TABLE table_name ( City, Value ) AS
SELECT 'Helsinki', 1 FROM DUAL UNION ALL
SELECT 'Helsinki', 2 FROM DUAL UNION ALL
SELECT 'Helsinki', 5 FROM DUAL UNION ALL
SELECT 'Kuopio', 4 FROM DUAL UNION ALL
SELECT 'Kuopio', 5 FROM DUAL UNION ALL
SELECT 'Joensuu', 1 FROM DUAL UNION ALL
SELECT 'Joensuu', 2 FROM DUAL UNION ALL
SELECT 'Joensuu', 3 FROM DUAL
查询:
SELECT city,
v.value
FROM ( SELECT LEVEL AS value
FROM DUAL
CONNECT BY LEVEL <= ( SELECT MAX( value ) FROM table_name )
-- or just 5 if you want a static value
) v
LEFT OUTER JOIN table_name t
PARTITION BY ( t.City )
ON ( v.value = t.value )
WHERE t.value IS NULL
输出:
CITY | VALUE :------- | ----: Helsinki | 3 Helsinki | 4 Joensuu | 4 Joensuu | 5 Kuopio | 1 Kuopio | 2 Kuopio | 3
db <>提琴here
答案 1 :(得分:1)
您可以CROSS JOIN
列出具有可能值(1到5)的不同城市,然后使用LEFT JOIN
反模式来识别缺少的值:
SELECT c.city, v.value
FROM
(SELECT DISTINCT city FROM mytable) c
CROSS JOIN (SELECT rownum value FROM DUAL CONNECT BY level<= 5) v
LEFT JOIN mytable t ON t.city = c.city AND t.value = v.value
WHERE t.city IS NULL
ORDER BY c.city, v.value
CITY | VALUE :------- | ----: Helsinki | 3 Helsinki | 4 Joensuu | 4 Joensuu | 5 Kuopio | 1 Kuopio | 2 Kuopio | 3
注意:生成值列表的另一种方法是从表中可用的不同值开始(而不是生成固定的数字列表)(这意味着表中所有可能的值都可用):>
CROSS JOIN (SELECT DISTINCT values FROM mytable) v
答案 2 :(得分:1)
您可以使用MINUS运算符实现此目标-您的原始想法
SQL> with city as (
2 select 'Helsinki' as name, 1 as value from dual union all
3 select 'Helsinki' as name, 2 as value from dual union all
4 select 'Helsinki' as name, 5 as value from dual union all
5 select 'Kuopio' as name, 4 as value from dual union all
6 select 'Kuopio' as name, 5 as value from dual union all
7 select 'Joensuu' as name, 1 as value from dual union all
8 select 'Joensuu' as name, 2 as value from dual union all
9 select 'Joensuu' as name, 3 as value from dual
10 )
11 SELECT NAME, LVL
12 FROM (SELECT DISTINCT NAME FROM CITY)
13 JOIN (SELECT LEVEL AS LVL FROM DUAL
14 CONNECT BY LEVEL <= 5) ON ( 1 = 1 )
15 MINUS
16 SELECT NAME, VALUE
17 FROM CITY
18 ORDER BY 1, 2;
NAME LVL
-------- ----------
Helsinki 3
Helsinki 4
Joensuu 4
Joensuu 5
Kuopio 1
Kuopio 2
Kuopio 3
7 rows selected.
SQL>
干杯!