我正在尝试一个简单的自我加入,但它的输出是一些不稳定的。
我的表(输入)如下所示:
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,在最后一行中有一些空值。我没有得到任何空值,但我得到一些我不知道如何到达那里的数字。此外,如果选择从我的表中显示更多字段,则返回的行数会增大。我不明白这种行为。有人可以帮我解决一下吗? (并且可能告诉我我做错了什么)。
答案 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')
;