即使不存在也输出具有空值的记录
Output records with null values even if not present
我在 Oracle
中有一个 table,如下所示
gen_id
serial_code
is_verified
1
fmcg
Y
1
smcg
Y
1
xmcg
N
2
smcg
Y
2
fmcg
Y
2
2mcg
Y
3
smcg
Y
3
amcg
Y
现在我想要最大 gen_id 的输出,在本例中为 3,serial_code 'smcg' 和 'fmcg'
我可以通过查询轻松获得输出,但我希望它采用如下格式。
gen_id
serial_code
is_verified
3
smcg
Y
3
fmcg
not_present
我怎样才能做到这一点?任何帮助深表感谢。
提前致谢
这样就可以了,但是看起来不是很漂亮。阅读代码中的注释。
SQL> WITH
2 test (gen_id, serial_code, is_verified)
3 AS
4 -- sample data
5 (SELECT 1, 'fmcg', 'Y' FROM DUAL
6 UNION ALL
7 SELECT 1, 'smcg', 'Y' FROM DUAL
8 UNION ALL
9 SELECT 1, 'xmcg', 'N' FROM DUAL
10 UNION ALL
11 SELECT 3, 'smcg', 'Y' FROM DUAL
12 UNION ALL
13 SELECT 3, 'amcg', 'Y' FROM DUAL),
14 maxgen (gen_id)
15 AS
16 -- MAX gen_id value; will be used later
17 (SELECT MAX (gen_id) FROM test),
18 temp
19 AS
20 -- compose NOT_PRESENT rows that don't exist in original (TEST) table
21 (SELECT t.gen_id, c.serial_code, 'not_present' is_verified
22 FROM test t
23 CROSS JOIN (SELECT DISTINCT serial_code
24 FROM test) c
25 JOIN maxgen m
26 ON m.gen_id = t.gen_id
27 AND (t.gen_id, c.serial_code) NOT IN
28 (SELECT gen_id, serial_code FROM test))
29 -- finally: union existing rows (from TEST) with NOT_PRESENT ones (from TEMP)
30 SELECT a.gen_id, a.serial_code, a.is_verified
31 FROM test a JOIN maxgen m ON m.gen_id = a.gen_id
32 WHERE serial_code IN ('smcg', 'fmcg')
33 UNION
34 SELECT x.gen_id, x.serial_code, x.is_verified
35 FROM temp x
36 WHERE x.serial_code IN ('smcg', 'fmcg');
GEN_ID SERIAL_CODE IS_VERIFIED
---------- ------------ -----------
3 fmcg not_present
3 smcg Y
SQL>
您可以为此使用 PARTITION
ed OUTER JOIN
。
来自 Oracle 12:
SELECT t.gen_id,
s.serial_code,
COALESCE(t.is_verified, 'not_present') AS is_verified
FROM (SELECT 'smcg' AS serial_code FROM DUAL UNION ALL
SELECT 'fmcg' FROM DUAL) s
LEFT OUTER JOIN (
SELECT *
FROM table_name
ORDER BY gen_id DESC
FETCH FIRST ROW WITH TIES
) t
PARTITION BY (gen_id)
ON (s.serial_code = t.serial_code)
在 Oracle 11 中,您可以使用:
SELECT t.gen_id,
s.serial_code,
COALESCE(t.is_verified, 'not_present') AS is_verified
FROM (SELECT 'smcg' AS serial_code FROM DUAL UNION ALL
SELECT 'fmcg' FROM DUAL) s
LEFT OUTER JOIN (
SELECT gen_id, serial_code, is_verified
FROM (
SELECT t.*,
RANK() OVER (ORDER BY gen_id DESC) AS rnk
FROM table_name t
)
WHERE rnk = 1
) t
PARTITION BY (gen_id)
ON (s.serial_code = t.serial_code)
其中,对于示例数据:
CREATE TABLE table_name (gen_id, serial_code, is_verified) AS
SELECT 1, 'fmcg', 'Y' FROM DUAL UNION ALL
SELECT 1, 'smcg', 'Y' FROM DUAL UNION ALL
SELECT 1, 'xmcg', 'N' FROM DUAL UNION ALL
SELECT 2, 'smcg', 'Y' FROM DUAL UNION ALL
SELECT 2, 'fmcg', 'Y' FROM DUAL UNION ALL
SELECT 2, '2mcg', 'Y' FROM DUAL UNION ALL
SELECT 3, 'smcg', 'Y' FROM DUAL UNION ALL
SELECT 3, 'amcg', 'Y' FROM DUAL;
双输出:
PARTITION BY (gen_id)
ON (s.serial_code = t.serial_code)
GEN_ID
SERIAL_CODE
IS_VERIFIED
3
fmcg
not_present
3
smcg
Y
我在 Oracle
中有一个 table,如下所示gen_id | serial_code | is_verified |
---|---|---|
1 | fmcg | Y |
1 | smcg | Y |
1 | xmcg | N |
2 | smcg | Y |
2 | fmcg | Y |
2 | 2mcg | Y |
3 | smcg | Y |
3 | amcg | Y |
现在我想要最大 gen_id 的输出,在本例中为 3,serial_code 'smcg' 和 'fmcg' 我可以通过查询轻松获得输出,但我希望它采用如下格式。
gen_id | serial_code | is_verified |
---|---|---|
3 | smcg | Y |
3 | fmcg | not_present |
我怎样才能做到这一点?任何帮助深表感谢。 提前致谢
这样就可以了,但是看起来不是很漂亮。阅读代码中的注释。
SQL> WITH
2 test (gen_id, serial_code, is_verified)
3 AS
4 -- sample data
5 (SELECT 1, 'fmcg', 'Y' FROM DUAL
6 UNION ALL
7 SELECT 1, 'smcg', 'Y' FROM DUAL
8 UNION ALL
9 SELECT 1, 'xmcg', 'N' FROM DUAL
10 UNION ALL
11 SELECT 3, 'smcg', 'Y' FROM DUAL
12 UNION ALL
13 SELECT 3, 'amcg', 'Y' FROM DUAL),
14 maxgen (gen_id)
15 AS
16 -- MAX gen_id value; will be used later
17 (SELECT MAX (gen_id) FROM test),
18 temp
19 AS
20 -- compose NOT_PRESENT rows that don't exist in original (TEST) table
21 (SELECT t.gen_id, c.serial_code, 'not_present' is_verified
22 FROM test t
23 CROSS JOIN (SELECT DISTINCT serial_code
24 FROM test) c
25 JOIN maxgen m
26 ON m.gen_id = t.gen_id
27 AND (t.gen_id, c.serial_code) NOT IN
28 (SELECT gen_id, serial_code FROM test))
29 -- finally: union existing rows (from TEST) with NOT_PRESENT ones (from TEMP)
30 SELECT a.gen_id, a.serial_code, a.is_verified
31 FROM test a JOIN maxgen m ON m.gen_id = a.gen_id
32 WHERE serial_code IN ('smcg', 'fmcg')
33 UNION
34 SELECT x.gen_id, x.serial_code, x.is_verified
35 FROM temp x
36 WHERE x.serial_code IN ('smcg', 'fmcg');
GEN_ID SERIAL_CODE IS_VERIFIED
---------- ------------ -----------
3 fmcg not_present
3 smcg Y
SQL>
您可以为此使用 PARTITION
ed OUTER JOIN
。
来自 Oracle 12:
SELECT t.gen_id,
s.serial_code,
COALESCE(t.is_verified, 'not_present') AS is_verified
FROM (SELECT 'smcg' AS serial_code FROM DUAL UNION ALL
SELECT 'fmcg' FROM DUAL) s
LEFT OUTER JOIN (
SELECT *
FROM table_name
ORDER BY gen_id DESC
FETCH FIRST ROW WITH TIES
) t
PARTITION BY (gen_id)
ON (s.serial_code = t.serial_code)
在 Oracle 11 中,您可以使用:
SELECT t.gen_id,
s.serial_code,
COALESCE(t.is_verified, 'not_present') AS is_verified
FROM (SELECT 'smcg' AS serial_code FROM DUAL UNION ALL
SELECT 'fmcg' FROM DUAL) s
LEFT OUTER JOIN (
SELECT gen_id, serial_code, is_verified
FROM (
SELECT t.*,
RANK() OVER (ORDER BY gen_id DESC) AS rnk
FROM table_name t
)
WHERE rnk = 1
) t
PARTITION BY (gen_id)
ON (s.serial_code = t.serial_code)
其中,对于示例数据:
CREATE TABLE table_name (gen_id, serial_code, is_verified) AS
SELECT 1, 'fmcg', 'Y' FROM DUAL UNION ALL
SELECT 1, 'smcg', 'Y' FROM DUAL UNION ALL
SELECT 1, 'xmcg', 'N' FROM DUAL UNION ALL
SELECT 2, 'smcg', 'Y' FROM DUAL UNION ALL
SELECT 2, 'fmcg', 'Y' FROM DUAL UNION ALL
SELECT 2, '2mcg', 'Y' FROM DUAL UNION ALL
SELECT 3, 'smcg', 'Y' FROM DUAL UNION ALL
SELECT 3, 'amcg', 'Y' FROM DUAL;
双输出:
PARTITION BY (gen_id)
ON (s.serial_code = t.serial_code)
GEN_ID SERIAL_CODE IS_VERIFIED 3 fmcg not_present 3 smcg Y