一段时间以来一直在苦苦挣扎,我基本上在数据库中有一个给定id的名字列表,我想在一列中选择id的第一个名称,并为id的其余名称选择进入逗号分隔的其他列。第二列的查询如下:
SELECT KittyName as KittyName, rowNo = ROW_NUMBER() OVER (Order By (select 1) ASC) FROM
(SELECT
(
SELECT KittyName + ','
FROM KittyNameTable
where KittyNameTable.Id = OtherKittyData.Id
FOR XML PATH('')
) as CombinedKittyNames
) as t2 WHERE rowNum > 1
此查询运行而没有rowNum子句生成两列:
KittyName rowNum
Fluffy 1
Jeff 1
Jeff 2
Marcus 1
但是当我加入它时,它说rowNum不是一列。
我尝试了一些但没有运气。有什么想法吗?
答案 0 :(得分:0)
尝试
select KittyName, RowNum
from
(SELECT KittyName as KittyName, rowNum
(SELECT
(
SELECT KittyName + ','
FROM KittyNameTable
where KittyNameTable.Id = OtherKittyData.Id
FOR XML PATH('')
) as CombinedKittyNames
) as t2 ) as x
Where RowNum = 1
答案 1 :(得分:0)
您不能在select
子句中使用where
中定义的别名。改为使用CTE或子查询:
WITH cte as (
SELECT KittyName as KittyName,
rowNum = ROW_NUMBER() OVER (Order By (select 1) ASC)
FROM (SELECT
(
SELECT KittyName + ','
FROM KittyNameTable
where KittyNameTable.Id = OtherKittyData.Id
FOR XML PATH('')
) as CombinedKittyNames
FROM OtherKittyData
) as t2
)
SELECT *
FROM CTE
WHERE rowNum > 1;
作为备注:您可能不希望在列表末尾添加逗号。此外,将XML从XML类型转换为字符串更安全,因此诸如&符号的字符不会转换为'&
。此查询看起来像:
WITH cte as (
SELECT ROW_NUMBER() OVER (Order By (select NULL)) as rowNum,
STUFF((SELECT ',' + KittyName
FROM KittyNameTable
WHERE KittyNameTable.Id = OtherKittyData.Id
FOR XML PATH('concat'), TYPE
).VALUE('/concat[1]', 'varchar(max)'),
1, 1, '') as CombinedKittyNames
FROM OtherKittyData
)
SELECT *
FROM CTE
WHERE rowNum > 1;
编辑:
如果您想要除第一个之外的所有Kitty名称,那么您将row_number()
放在错误的位置。提示:在提问时,请包含样本数据和所需结果。
SELECT okd.*,
STUFF((SELECT ',' + KittyName
FROM (SELECT knt.*,
ROW_NUMBER() OVER (Order By (select NULL)) as rowNum
FROM KittyNameTable knt
) knt
WHERE knt.Id = okd.Id AND
rowNum > 1
FOR XML PATH('concat'), TYPE
).VALUE('/concat[1]', 'varchar(max)'),
1, 1, '') as CombinedKittyNames
FROM OtherKittyData okd;
换句话说,你必须在里面过滤子查询。
顺便说一句,在这种情况下,你不应该使用order by
和常量。没有"第一"行。您应该使用显式排序列(例如id)。