SQL 查询将第一行与其余行分开
SQL query separating the first row from the rest
为此苦苦挣扎了一段时间,我基本上在数据库中有一个给定 id 的名称列表,我想 select 将 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 不是一列。
我尝试了一些方法但没有成功。有什么想法吗?
尝试
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
您不能在 where
子句的 select
中使用定义的别名。请改用 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
与常量一起使用。没有 "first" 行。您应该使用明确的排序列(例如 id)。
为此苦苦挣扎了一段时间,我基本上在数据库中有一个给定 id 的名称列表,我想 select 将 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 不是一列。
我尝试了一些方法但没有成功。有什么想法吗?
尝试
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
您不能在 where
子句的 select
中使用定义的别名。请改用 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
与常量一起使用。没有 "first" 行。您应该使用明确的排序列(例如 id)。