在同一张表中合并两个列

5

假设我在同一张表中有以下两列:

Column 1
--------
1
2
3

Column 2
--------
4
5
6

我该如何得到一个能给我以下结果的答案?
Columns
--------
1
2
3
4
5
6

编辑

我真正想要的是确保在不必多次重复表格和where条件的情况下,在同一张表格上键入联合查询的更有效方法。

实际查询看起来更像这样:

WITH T1 AS 
( SELECT [Col1] FROM [Table1] 
)
SELECT * FROM (
    SELECT [Cols1-100], COUNT(*) as "Count" FROM (

        SELECT [Col-1] FROM [Table2] AS [Cols1-100], [T1] 
        WHERE [Table2].[Col-1] = [T1].[Col-1] 
        AND [Col-1] != '2' AND [Col-2] != '2' ..... etc ..... AND [Col-100] != '2'
        UNION ALL

        SELECT [Col-2] FROM [Table2] AS [Cols1-100], [T1] 
        WHERE [Table2].[Col-1] = [T1].[Col-1] 
        AND [Col-1] != '2' AND [Col-2] != '2' ..... etc ..... AND [Col-100] != '2'
        UNION ALL

        ....................... etc
        ....................... etc
        ....................... etc
        .... etc

        SELECT [Col-100] FROM [Table2] AS [Cols1-100], [T1] 
        WHERE [Table2].[Col-1] = [T1].[Col-1] 
        AND [Col-1] != '2' AND [Col-2] != '2' ...... etc .... AND [Col-100] != '2'

    ) as [Temp1]
    GROUP BY [Cols1-100]    
) as [Temp2]

使用@Bohemian的外部查询,我可以做到以下操作,但是测试两个查询时,似乎速度变慢了很多。

WITH T1 AS 
( SELECT [Col1] FROM [Table1] 
)
SELECT * FROM (
    SELECT [Cols1-100], COUNT(*) as "Count" FROM (
            SELECT * FROM (
                SELECT [Col-1] AS [Cols1-100], [Col-1], [Col-2], ..etc.. [Col-100] FROM [Table2] 
                UNION ALL
                SELECT [Col-2] AS [Cols1-100], [Col-1], [Col-2], ..etc.. [Col-100] FROM [Table2] 
                UNION ALL
                ....................... etc
                .... etc
                SELECT [Col-100] AS [Cols1-100], [Col-1], [Col-2], ..... etc ..... [Col-100] FROM [Table2] 
            ) AS SUBQUERY WHERE [Col-1] IN (SELECT [Col1] FROM [T1])
            AND [Col-1] != '2' AND [Col-2] != '2' ..... etc ..... AND [Col-100] != '2' 
        ) as [Temp1]
    GROUP BY [Cols1-100]    
) as [Temp2]

1
关于你在另一个答案中的评论:有一些(非标准!)合并多个列的方法比UNION更简洁,但如果你经常需要这样做,那很可能是数据库设计不良的迹象。你能否提供更多关于你试图解决的实际问题的信息,也许我们可以建议一种改进基本设计的方法,以便你不需要这种“魔法”非标准SQL? - SingleNegationElimination
3个回答

15
select column1 as columns from mytable
union
select column2 from mytable

使用union可以去除重复项(在某些数据库上还可以进行排序)。
如果你想保留重复项,请使用union all

select column1 as columns from mytable
union all
select column2 from mytable

编辑:

为了添加一个where子句,简单但效率低下的执行方式是将其作为外部查询添加:

select * from (
    select column1 as columns from mytable
    union
    select column2 from mytable ) x
where columns ...

更为高效的执行方式是将其放在每个子查询中,但这会导致查询时间变得非常长。

select column1 as columns from mytable
where ....
union
select column2 from mytable
where ...

如果我想联合100个列并使用where子句,我需要打出以下代码吗?select column1 as columns from mytable where ... union all select column2 from mytable where ... union all select column3 from mytable where ... ..... ..... ..... union all select column100 from mytable where ...难道没有更快的方法可以打出这样的代码吗?select union all column1, column3, column4, column5, column6 as columns from mytable where .... - edezzie
@edezzie- 你需要使用99个union将100个select语句连接起来,才能实现你所说的将100列合并的操作。 - Chris Smith
@Bohemian- union 不一定会排序。它只是将集合组合在一起并删除重复项。如果需要排序,请使用 order by。数据库引擎可能使用排序来删除重复项,也可能使用哈希表(任意顺序)或其他方法。 - Chris Smith
@ChrisSmith 或许规范是 union 不排序,但我用过的每个数据库都会排序。 - Bohemian
1
@Bohemian - 你的情况可能不同,但我经常看到 MS SQL Server 使用哈希联合,特别是数据集很大的时候。 - Chris Smith
1
@ChrisSmith 好的很酷 - 我没有使用过MSSQL。这是个不错的知识点。谢谢。我已经相应地编辑了答案。 - Bohemian

3

如果您不想使用union,因为您需要多次重复相同的where子句,那么有一个[非常糟糕的]解决方法:

select decode(j.col, 1, column1, 2, column2)
from table t
join (select 1 as col from dual union select 2 from dual) j
 on 1 = 1
where (your where clause)

这个例子来自oracle,在SQLServer中不需要“from dual”。

另外,如果你有很多列要连接(实际上不应该发生),你可以在“join”内部使用分层查询来避免大量的“unions”。


在我的情况下,“from table” 是另一个庞大的查询。因此,只使用一次 from 子句有助于缩小查询。 - Yiğit

0
你试过UNPIVOT吗?这取决于你使用的SQL Server版本,但以下示例适用于SQL 2008:
DECLARE @t TABLE (Col1 INT, col2 INT, col3 INT)
INSERT INTO @t
        ( Col1, col2, col3 )
VALUES  ( 1, -- Col1 - int
          2, -- col2 - int
          3  -- col3 - int
          ),
          ( 4, -- Col1 - int
          5, -- col2 - int
          6  -- col3 - int
          )


 SELECT  cols
 FROM (SELECT col1, col2, col3 FROM @t) pvt
 UNPIVOT
 (Cols FOR ID IN (col1, col2, col3))  unpvt     
 WHERE cols <> 2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接