1

我正在尝试一个简单的自连接,但它的输出有些不稳定。

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

 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,最后有几个空值。我没有得到任何空值,但我确实得到了一些我不知道如何到达那里的数字。此外,如果选择从我的表中显示更多字段,则返回的行数会变得更大。我不明白这种行为。有人可以帮我解决吗?(并且可能告诉我我做错了什么)。

4

2 回答 2

2

你不能有效地做到这一点。连接左侧和右侧的行之间没有关系。加入需要关系;您的ON条件未指定两者之间的关系,因此您会看到比您预期的多得多的行。

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

于 2013-10-23T15:18:00.183 回答
1

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

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')
;
于 2013-10-23T15:47:10.710 回答