【问题标题】:Joining two select queries from the same table连接来自同一个表的两个选择查询
【发布时间】:2013-01-16 21:21:13
【问题描述】:

该表包含一个 ID 列、一个 valueHeading 列和一个 value 列。我想根据值具有的 valueHeading 类型将 value 列分为两个新列 valueHeading1 和 valueHeading2。

所以我想加入这个选择: 编辑:完全加入

SELECT ID
      ,valueHeading
      ,value as 'valueHeading1'
FROM table1
WHERE valueHeading = 'valueHeading1'

使用此选择:

SELECT ID
      ,value as 'valueHeading2'
FROM table1
WHERE valueHeading = 'valueHeading2'

在他们各自的 ID 上。我该怎么做?

编辑来说明我想要做什么:

原表:

ID    valueHeading    value
0     valueHeading1    a
0     valueHeading2    a
1     valueHeading1    ab
1     valueHeading2    NULL
2     valueHeading1    abcd
2     valueHeading2    abc

新表:

ID    valueHeading1    valueHeading2
0          a               a
1          ab              NULL
2         abcd             abc

【问题讨论】:

  • 我添加了 SQLServer 标签,因为它似乎是您正在使用的数据库 :)
  • 是的,抱歉我没说清楚。

标签: sql sql-server select join


【解决方案1】:

自加入可能是一个简单的解决方案

SELECT DISTINCT t1.ID, t1.value as valueHeading1, t2.value as valueHeading2, 
FROM table1 t1
INNER JOIN table1 t2 ON t1.ID = t2.ID
WHERE t1.valueHeading <> t2.valueHeading

【讨论】:

    【解决方案2】:

    如果您只需要加入,请使用此选项。如果您不需要加入,则使用 case when 是一种优雅的方式。

    SELECT * FROM 
        (SELECT ID
              ,valueHeading
              ,value as 'valueHeading1'
        FROM table1
        WHERE valueHeading = 'valueHeading1') AS TAB_1, 
        (SELECT ID
              ,value as 'valueHeading2'
        FROM table1
        WHERE valueHeading = 'valueHeading2') AS TAB_2
        WHERE TAB_1.ID = TAB_2.ID
    

    【讨论】:

      【解决方案3】:

      在 SQLServer2005+ 中可能使用 PIVOT

      SELECT ID, valueHeading1, valueHeading2
      FROM
      (
       SELECT *
       FROM dbo.test28
       WHERE valueHeading IN ('valueHeading1', 'valueHeading2')
       ) x
       PIVOT
       (
        MAX(value)
        FOR valueHeading IN ([valueHeading1], [valueHeading2])
        ) p
      

      SQLFiddle上的演示

      【讨论】:

      • 这看起来很干净。
      • @mdc 如果你正在使用 MSSQL,你绝对应该使用这个。
      【解决方案4】:

      尝试类似:

      SELECT ID
            , CASE WHEN valueHeading = 'valueHeading1' THEN value ELSE NULL END AS valueHeading1
            , CASE WHEN valueHeading = 'valueHeading2' THEN value ELSE NULL END AS valueHeading2
      FROM table1
      WHERE valueHeading IN ('valueHeading1', 'valueHeading2')
      

      如果您想为每个 ID 重新组合一行中的所有值,您可以尝试:

      SELECT ID
            , MAX(CASE WHEN valueHeading = 'valueHeading1' THEN value ELSE NULL END) AS valueHeading1
            , MAX(CASE WHEN valueHeading = 'valueHeading2' THEN value ELSE NULL END) AS valueHeading2
      FROM table1
      WHERE valueHeading IN ('valueHeading1', 'valueHeading2')
      GROUP BY ID
      HAVING MAX(CASE WHEN valueHeading = 'valueHeading1' THEN value ELSE NULL END) IS NOT NULL
      OR MAX(CASE WHEN valueHeading = 'valueHeading2' THEN value ELSE NULL END) IS NOT NULL
      

      SQLFiddle。我还在 Oracle 11g 和 MSSQL 2012 上进行了尝试,并且每次都有效。

      【讨论】:

      • 我认为应该是value 而不是valueHeading。 IE; CASE WHEN valueHeading = 'valueHeading1' THEN value ELSE NULL END AS valueHeading1
      • 是的,我需要的不是 valueHeading。然而,这似乎只是用值填充 valueHeading1 或 valueHeading2。不是他们两个?如果我加入我发布的两个选择,那么 valueHeading1 和 valueHeading2 列中都会有值,对吧?
      • 这仅填充其中一个,其他为空。你到底需要什么?
      • @Kaf 我需要两个选择之间的完全连接。即使只有一个具有值的行。如果两者都有值,那么这两个值都应该存在。
      • 我在意识到您需要什么后试图回答您的问题。这是SQL Fiddle,它的作用不同。
      猜你喜欢
      • 2016-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-02
      • 1970-01-01
      • 1970-01-01
      • 2013-02-06
      • 1970-01-01
      相关资源
      最近更新 更多