我将此数据作为树:
身份证 | 名字 | t1 | t2 | t3 | 完整 |
---|---|---|---|---|---|
1 | A | 59 | 空 | 空 | 59 |
2 | B | 59 | 20 | 空 | 59.02 |
3 | C | 59 | 40 | 空 | 59.04 |
4 | D | 59 | 60 | 空 | 59.06 |
5 | E | 59 | 60 | 01 | 59.060.01 |
6 | F | 59 | 60 | 10 | 59.060.10 |
正如我所提到的,该表是一棵树,因此 t1 是父级,t2 是第一个子级,t3 是第二个子级。 所以如果 t2 和 t3 为 null 则意味着它是父级。
59
/ | \
20 40 60
/ \
01 10
这就是我期望的结果:
身份证 | 名字 | t1 | t2 | t3 | 完整 |
---|---|---|---|---|---|
1 | A | 59.A | 空 | 空 | 59 |
2 | B | 59.A | 020.B | 空 | 59.02 |
3 | C | 59.A | 040.C | 空 | 59.04 |
4 | D | 59.A | 060.D | 空 | 59.06 |
5 | E | 59.A | 060.D | 01.E | 59.060.01 |
6 | F | 59.A | 060.D | 10.F | 59.060.10 |
为了使其可读,我想连接每个 (t) 及其名称,如上表所示,因此我创建了此查询。
SELECT
Id,
name,
MAX(CASE WHEN t2 = '' AND t3 = '' THEN CONCAT([t1],'.', [ICSAr]) ELSE null END) OVER (PARTITION BY t1) AS t1,
MAX(CASE WHEN t1 != '' AND t3 = '' AND t2 != '' THEN CONCAT([t2],'.', [name]) ELSE NULL END) OVER (PARTITION BY t1,[t2]) AS t2,
CASE WHEN [t3] != '' THEN CONCAT([t3],'.', [name]) END AS [t3]
FROM [table]
但是如果我使用基于 t2 或 t3 的 where 条件,结果将不正确,因为它给出的是基于条件的结果。
前
1-
WHERE t1= 59 and t2 = 020
身份证 | 名字 | t1 | t2 | t3 |
---|---|---|---|---|
2 | B | 空 | 020.B | 空 |
我期望的结果是:
身份证 | 名字 | t1 | t2 | t3 |
---|---|---|---|---|
2 | B | 59.A | 020.B | 空 |
2-
WHERE t1= 59 and t3 = 10
身份证 | 名字 | t1 | t2 | t3 |
---|---|---|---|---|
6 | F | 空 | 空 | 10.F |
我期望的结果是:
身份证 | 名字 | t1 | t2 | t3 |
---|---|---|---|---|
6 | F | 59.A | 060.D | 10.F |
即使有条件,如何查询所有表?
假设 SQL Server,您可以使用
FIRST_VALUE()
,因为 NULL 是先排序的。
这与在窗口中使用
MAX(CASE WHEN x IS NULL THEN name END)
类似。
两个版本如下...
CREATE TABLE your_table (
id INT,
name CHAR,
t1 INT,
t2 INT,
t3 INT,
fullT VARCHAR(11)
)
INSERT INTO
your_table
VALUES
(1, 'A', 59, null, null, '59'),
(2, 'B', 59, 20, null, '59.02'),
(3, 'C', 59, 40, null, '59.04'),
(4, 'D', 59, 60, null, '59.06'),
(5, 'E', 59, 60, 01, '59.060.01'),
(6, 'F', 59, 60, 10, '59.060.10')
WITH
name_lookup AS
(
SELECT
id,
name,
t1, t2, t3,
FIRST_VALUE(name) OVER (PARTITION BY t1 ORDER BY t1, t2, t3) AS name1,
FIRST_VALUE(name) OVER (PARTITION BY t1, t2 ORDER BY t1, t2, t3) AS name2,
FIRST_VALUE(name) OVER (PARTITION BY t1, t2, t3 ORDER BY t1, t2, t3) AS name3
FROM
your_table
)
SELECT
id,
name,
t1, t2, t3,
CASE WHEN t1 IS NOT NULL THEN name1 END AS name1,
CASE WHEN t2 IS NOT NULL THEN name2 END AS name2,
CASE WHEN t3 IS NOT NULL THEN name3 END AS name3
FROM
name_lookup
ORDER BY
id
id | 名字 | t1 | t2 | t3 | 姓名1 | 名称2 | 名称3 |
---|---|---|---|---|---|---|---|
1 | A | 59 | 空 | 空 | A | 空 | 空 |
2 | B | 59 | 20 | 空 | A | B | 空 |
3 | C | 59 | 40 | 空 | A | C | 空 |
4 | D | 59 | 60 | 空 | A | D | 空 |
5 | E | 59 | 60 | 1 | A | D | E |
6 | F | 59 | 60 | 10 | A | D | F |
WITH
name_lookup AS
(
SELECT
id,
name,
t1, t2, t3,
MAX(CASE WHEN t2 IS NULL THEN name ELSE NULL END) OVER (PARTITION BY t1 ) AS name1,
MAX(CASE WHEN t3 IS NULL THEN name ELSE NULL END) OVER (PARTITION BY t1, t2 ) AS name2,
MAX( name ) OVER (PARTITION BY t1, t2, t3) AS name3
FROM
your_table
)
SELECT
id,
name,
t1, t2, t3,
CASE WHEN t1 IS NOT NULL THEN name1 END AS name1,
CASE WHEN t2 IS NOT NULL THEN name2 END AS name2,
CASE WHEN t3 IS NOT NULL THEN name3 END AS name3
FROM
name_lookup
ORDER BY
id
id | 名字 | t1 | t2 | t3 | 姓名1 | 名称2 | 名称3 |
---|---|---|---|---|---|---|---|
1 | A | 59 | 空 | 空 | A | 空 | 空 |
2 | B | 59 | 20 | 空 | A | B | 空 |
3 | C | 59 | 40 | 空 | A | C | 空 |
4 | D | 59 | 60 | 空 | A | D | 空 |
5 | E | 59 | 60 | 1 | A | D | E |
6 | F | 59 | 60 | 10 | A | D | F |