SQL 多对一联接 - 如何获取空白字段而不是重复值

SQL many-to-one join - how to get blank fields instead of duplicated values

我有 3 个表:

CREATE TABLE ticket (
       ticket_id int,
       description varchar(1000));

CREATE TABLE document (
       ticket_id int,
       file_name varchar(1000));

CREATE TABLE flex_fields (
       ticket_id int,
       field_name varchar(1000),
       field_value varchar(1000));

当我通过 ticket_id 加入这个表并查询时,我得到这样的结果:

ticket_id   description         file_name   field_name     field_value

4374959     some_description1   file1.txt   created_date   12-12-12
4374959     some_description1   file1.txt   created_by     Johnny D.
4374959     some_description1   image.png   add_info       Empty
4374959     some_description1   image.png   country_id     UK
1111111     text                report.xls  created_date   12-12-12
1111111     text                image2.png  created_by     Sarah C.
1111111     text                image2.png  report_size    123123
1111111     text                image3.png  modified_date  13-12-12
1111111     text                image3.png  modified_by    James B.

但我想清空重复的值并得到这样的结果:

ticket_id   description         file_name   field_name     field_value

4374959     some_description1   file1.txt   created_date   12-12-12
                                image.png   created_by     Johnny D.
                                            add_info       Empty
                                            country_id     UK
1111111     text                report.xls  created_date   12-12-12
                                image2.png  created_by     Sarah C.
                                image3.png  report_size    123123
                                            modified_date  13-12-12
                                            modified_by    James B.

是否可以得到这样的结果集? 我在 AWS Athena(Presto SQL) 工作,但我真的很感谢你的 ideas/suggestions,不管 dbms。谢谢!

请注意,您不应该在 SQL 中执行此操作,因为这是表示层问题,而不是数据层问题 - 相反,您应该仅在以下位置过滤掉重复的列数据您正在渲染 HTML table 或以某种方式渲染到屏幕。

但是,如果出于某些可怕的原因您需要在 SQL 中执行此操作,则类似的方法应该可行。

  • 注意重复使用显式 ORDER BY 子句以确保正确性:从不依赖隐式排序
  • 另请注意,CTE 和其他子查询不能有 ORDER BY:只有顶级 SELECT 查询可以有 ORDER BY 子句,因此需要 ROW_NUMBER() OVER ( ORDER BY ...) 在 CTE 中。
  • 我的查询使用 ticket_id 作为 description 列,因为我假设 description 是由 ticket_id 键入的,如果不是,那么您需要比较 description 直接。
    • 请注意,文本比较不区分大小写,这可能是可取的,也可能不是,否则请使用显式 COLLATION 指定区分大小写的比较。

WITH t AS (
    SELECT
        ROW_NUMBER() OVER ( ORDER BY ticket_id, file_name, field_name ) AS n,
        ticket_id,
        description,
        file_name,
        field_name,
        field_value
    FROM
        etc
)
SELECT
    NULLIF( LAG( t.ticket_id  , 1 ) OVER ( ORDER BY t.n ) = t.ticket_id, t.ticket_id     ) AS ticket_id,
    NULLIF( LAG( t.ticket_id  , 1 ) OVER ( ORDER BY t.n ) = t.ticket_id, t.description   ) AS description,
    NULLIF( LAG( t.file_name  , 1 ) OVER ( ORDER BY t.n ) = t.file_name, t.file_name     ) AS file_name,
    NULLIF( LAG( t.field_name , 1 ) OVER ( ORDER BY t.n ) = t.field_name, t.field_name   ) AS field_name, 
    NULLIF( LAG( t.field_value, 1 ) OVER ( ORDER BY t.n ) = t.field_value, t.field_value ) AS field_value
FROM
    t
ORDER BY
    t.ticket_id,
    t.file_name,
    t.field_name