使用分区SQL过滤

问题描述 投票:0回答:1

我将此数据作为树:

身份证 名字 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 partition
1个回答
0
投票

假设 SQL Server,您可以使用

FIRST_VALUE()
,因为 NULL 是先排序的。

  • 不同的 DBMS 对 NULL 的排序不同
  • 因此,指定您的 DBMS 至关重要

这与在窗口中使用

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

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.