T-sql内部加入不稳定的行为

时间:2013-10-23 14:57:58

标签: sql sql-server tsql

我正在尝试一个简单的自我加入,但它的输出是一些不稳定的。

我的表(输入)如下所示:

 ID  |   Value    
 1   |    val1   
 1   |    val2   
 1   |    val3  
 2   |    val4   
 2   |    val5   
 2   |    val6  
 2   |    val7

我想要实现的目标如下:

 ID 1  |   Value 1  | ID 2  |   Value 2  
 1     |    val1    | 2     |   val4   
 1     |    val2    | 2     |   val5  
 1     |    val3    | 2     |   val6  
 Null  |    Null    | 2     |   val7  

我尝试实现此输出的目的如下:

SELECT DISTINCT 
    column1.ID,
    column1.value,
    column2.ID,
    column2.value
FROM table column1   
INNER JOIN table column2 ON column1.ID = 1 AND column2.ID = 2    

这段代码返回错误的行数;我应该获得的总行数是4,在最后一行中有一些空值。我没有得到任何空值,但我得到一些我不知道如何到达那里的数字。此外,如果选择从我的表中显示更多字段,则返回的行数会增大。我不明白这种行为。有人可以帮我解决一下吗? (并且可能告诉我我做错了什么)。

2 个答案:

答案 0 :(得分:2)

你无法有效地做到这一点。连接的左侧和右侧之间的行没有关系。联接需要一种关系;你的ON条件没有指定两者之间的关系,所以你会看到比你想要的更多的行。

如果您尝试使用SQL格式化数据以进行显示,请勿。获取您的数据,然后在客户端应用程序中对其进行格式化。

答案 1 :(得分:1)

您将不同CTE或子查询中的数据集分开,并在此过程中使用ROW_NUMBER()函数按值的顺序分配行号。最后加入两个行号 - 但是使用FULL而不是INNER join,这样你就可以在行数较少的任何一方获得空值。

WITH CTE_1 AS 
(
    SELECT *, ROW_NUMBER() OVER (ORDER BY [Value]) AS RN
    FROM dbo.table1
    WHERE ID = 1
)
, CTE_2 AS 
(
    SELECT *, ROW_NUMBER() OVER (ORDER BY [Value]) AS RN
    FROM dbo.table1
    WHERE ID = 2
)
SELECT 
    c1.ID AS ID1 
  , c1.VALUE AS Value1
  , c2.ID AS ID2
  , c2.VALUE AS Value2
FROM CTE_1 c1
FULL JOIN CTE_2 c2 ON c1.RN = c2.RN

SQLFIddle目前无法正常工作,我无法设置演示,但这里是我使用过的示例表:

CREATE TABLE Table1
    ([ID] int, [Value] varchar(4))
;

INSERT INTO Table1
    ([ID], [Value])
VALUES
    (1, 'val1'),
    (1, 'val2'),
    (1, 'val3'),
    (2, 'val4'),
    (2, 'val5'),
    (2, 'val6'),
    (2, 'val7')
;