【问题标题】:Combining multiple rows into one row where the data in only one column changes and adding the data for the varied column onto the end of the row将多行合并为一行,其中只有一列中的数据发生变化,并将变化列的数据添加到行尾
【发布时间】:2013-02-20 13:16:12
【问题描述】:

我希望你能帮助我,因为我的 sql 非常基础。以下是我的查询:

我的数据如下所示:

Policy Number | Commission Amount | Relationship | PersonLinked
50422         | 1000.00           | Owner        | John Smith
50422         | 1000.00           | Advisor      | Richard Bass
50422         | 1000.00           | Port Man     | Craig Thomson
74857         | 500.00            | Owner        | Karen Jones
98765         | 20000.00          | Owner        | Tim Crosby
98765         | 20000.00          | Port Man     | Josh Bishop

但是我想在一行中显示所有数据,所以它看起来像这样:

Policy Number | Commission Amount | Owner          | Advisor        | Port Man
50422         | 1000.00           | John Smith     | Richard Bass   | Craig Thomson
74857         | 500.00            | Karen Jones    |                |
98765         | 20000.00          | Tim Crosby     |                | Josh Bishop

如果可以以这种方式操作数据,请告诉我 SQL 是什么。我真的被困住了。请帮忙。

【问题讨论】:

标签: sql


【解决方案1】:

除非从一开始就知道有固定的、静态数量的关系,否则答案是:NO。您不能进行返回可变列数的 SQL 查询。

你的机会是: - 如果您使用的是专有的 SQL rdbms,可能会有一些旋转功能 - 如果您使用任何类型的语言(如 PHP、VBA)来创建查询 - 那么您可以在查询可能的关系后动态创建它。

【讨论】:

  • @xQbert:这正是我在我的分析器中所写的:要么使用数据透视(专有),要么使用动态创建的查询(取决于所使用的技术,它可能被不同地调用;“动态 SQL”,“字符串连接”,无论如何)。您在评论中重复我的回答是否有意义?
  • 我对您的第一个说法感到困惑,除非它的列数固定,否则无法完成,然后继续解释如何为可变列数完成它。 OP 没有对如何实现我看到的预期结果施加任何限制;所以当我读到“不,它不能完成”时,我不同意。
  • @xQbert:我只是说它不能在 SQL 中完成 - 以及原因。该问题被标记为“SQL”,没有提到特定的供应商或脚本语言。简单的“不”可能是我的回答的结尾,但我觉得它是不完整的,而不提醒在现实生活中我们通常拥有比 SQL 更多的工具:就像某种用于动态生成 SQL 查询的环境(任何程序语言会做)。或一些 RDBMS 扩展(如 pivot)。你还在迷茫吗?还有什么我可以解释的吗?
  • 没有。任何进一步的对话都无助于为问题提供答案。
  • @xQbert:谢谢,你展示了我缺乏的品位和机智。 EOT。
【解决方案2】:

这是假设您在每个保单编号的每个角色中都有一个角色,并且您需要显示的唯一角色是这三个角色。

Select [own].[Policy Number], 
       [own].[Commission Amount],
       [own].[PersonLinked] as [Owner],
       [adv].[PersonLinked] as [Advisor],
       [port].[PersonLinked] as [Port Man]
From   PolicyRoles as [own]
Join   PolicyRoles as [adv] on [own].[Policy Number] = [adv].[Policy Number]
                            and [adv].[Relationship] = 'Advisor'
Join   PolicyRoles as [port] on [own].[Policy Number] = [port].[Policy Number]
                             and [port].[Relationship] = 'Port Man'
Where  [own].[Relationship] = 'Owner'

【讨论】:

    【解决方案3】:

    试试这个查询

    Select a.Policy Number, a.Commission Amount, a.PersonLinked as 'Owner', b.PersonLinked 'Advisor', c.PersonLinked as 'Port Man' 
    FROM tbl a, tbl b, tbl c
    WHERE a.Policy Number = b.Policy Number AND a.Policy Number = c.Policy Number AND
    b.Policy Number = c.Policy Number AND a.Relationship = 'Owner' AND 
    b.Relationship = 'Advisor' AND c.Relationship = 'Port Man';
    

    【讨论】:

      【解决方案4】:

      首先,您的答案取决于您未指定的 SQL 版本。每个版本中都有允许您连接的功能。值,例如将表数据转换为字符串。在 Oracle - LISTAGG()、MY SQL - GROUP_CONCAT() 等... 除非您为每个案例创建视图或表,否则无法在 SQL 中创建动态列。您可以创建表作为选择您需要的所有列并从 your_table 添加更多列,您还可以创建具有不同列数的视图。您需要在您的 SQL 版本中对此进行研究。所有带有 CASE 表达式的示例都很好,但我会进行研究,看看您的 SQL 版本中有什么可用的,因为 LISTAGG() 或 GROUP_CONCAT() 是您真正想要的,而不是 CASE。这是创建“动态”列的 Oracle 示例。 emp表是Oracle使用的现有表:

      CREATE TABLE test_tab AS
       SELECT empno
            , ename
            , ename "OWNER" -- This column name is OWNER and datatype is the same as ename 
        FROM scott.emp
       WHERE 1=2 -- False - empty table is created, no data...
      /
      
      -- Describe newly created table:
      
      SQL> desc test_tab  
      
      Column Name  Data Type 
      --------------------------------
      EMPNO    NUMBER (4)              
      ENAME    VARCHAR2 (10 Byte)        
      OWNER    VARCHAR2 (10 Byte) 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-11
        • 1970-01-01
        相关资源
        最近更新 更多