Sql server 如何按ObjectId对表进行分组?
我对SQL有点熟悉 我使用Sql Server 2012 我有这张桌子:Sql server 如何按ObjectId对表进行分组?,sql-server,tsql,group-by,Sql Server,Tsql,Group By,我对SQL有点熟悉 我使用Sql Server 2012 我有这张桌子: |Id | SiteId| IsNormal| DateReview | ObjectId |FrequencyId|InspectionId | |3379| 5| 1 | 2016-09-08 00:00:00.000| 1019 | 1 | 16 | |3380| 5| 1 | 2016-
|Id | SiteId| IsNormal| DateReview | ObjectId |FrequencyId|InspectionId |
|3379| 5| 1 | 2016-09-08 00:00:00.000| 1019 | 1 | 16 |
|3380| 5| 1 | 2016-09-08 00:00:00.000| 1019 | 1 | 20 |
|3381| 5| 0 | 2016-09-08 00:00:00.000| 1020 | 1 | 16 |
|3382| 5| 1 | 2016-09-08 00:00:00.000| 1020 | 1 | 54 |
我需要按ObjectId对表进行GROUP,如果在GROUP表中至少有一行具有false属性,则必须为false
下面是所需的分组表:
|Id | SiteId| IsNormal | DateReview | ObjectId |FrequencyId|InspectionId |
|3379,3380 | 5 | 1 | 2016-09-08 00:00:00.000| 1019 | 1 | 16,20 |
|3382,3381 | 5 | 0 | 2016-09-08 00:00:00.000| 1020 | 1 | 54,16 |
IsNormal列是位类型。请这样尝试
DECLARE @Table TABLE (
Id INT
,SiteId INT
,IsNormal bit
,DateReview DATETIME
,ObjectId INT
,FrequencyId INT
,InspectionId INT
)
Insert into @Table values
(3379,5,1, '2016-09-08 00:00:00.000',1019,1,16)
,(3380,5,1, '2016-09-08 00:00:00.000',1019,1,20)
,(3381,5,0,'2016-09-08 00:00:00.000',1020,1,16)
,(3382,5,1, '2016-09-08 00:00:00.000',1020,1,54)
SELECT STUFF((
SELECT ',' + convert(VARCHAR(10), Id)
FROM @Table t
WHERE t.ObjectId = t1.objectid
FOR XML PATH('')
), 1, 1, '') AS Id
,siteid
,CASE
WHEN STUFF((
SELECT ',' + convert(VARCHAR(10), IsNormal)
FROM @Table t
WHERE t.ObjectId = t1.objectid
FOR XML PATH('')
), 1, 1, '') LIKE '%0%'
THEN 0
ELSE 1
END AS IsNormal
,datereview
,objectid
,FrequencyId
,STUFF((
SELECT ',' + convert(VARCHAR(10), InspectionId)
FROM @Table t
WHERE t.ObjectId = t1.objectid
FOR XML PATH('')
), 1, 1, '') AS InspectionId
FROM @Table t1
GROUP BY siteid
,datereview
,objectid
,FrequencyId
试着这样,
DECLARE @Table TABLE (
Id INT
,SiteId INT
,IsNormal bit
,DateReview DATETIME
,ObjectId INT
,FrequencyId INT
,InspectionId INT
)
Insert into @Table values
(3379,5,1, '2016-09-08 00:00:00.000',1019,1,16)
,(3380,5,1, '2016-09-08 00:00:00.000',1019,1,20)
,(3381,5,0,'2016-09-08 00:00:00.000',1020,1,16)
,(3382,5,1, '2016-09-08 00:00:00.000',1020,1,54)
SELECT STUFF((
SELECT ',' + convert(VARCHAR(10), Id)
FROM @Table t
WHERE t.ObjectId = t1.objectid
FOR XML PATH('')
), 1, 1, '') AS Id
,siteid
,CASE
WHEN STUFF((
SELECT ',' + convert(VARCHAR(10), IsNormal)
FROM @Table t
WHERE t.ObjectId = t1.objectid
FOR XML PATH('')
), 1, 1, '') LIKE '%0%'
THEN 0
ELSE 1
END AS IsNormal
,datereview
,objectid
,FrequencyId
,STUFF((
SELECT ',' + convert(VARCHAR(10), InspectionId)
FROM @Table t
WHERE t.ObjectId = t1.objectid
FOR XML PATH('')
), 1, 1, '') AS InspectionId
FROM @Table t1
GROUP BY siteid
,datereview
,objectid
,FrequencyId
您可以使用以下命令:
WITH Src AS
(
SELECT * FROM (VALUES
(3379, 5, CAST(1 AS bit), '2016-09-08 00:00:00.000', 1019, 1, 16),
(3380, 5, CAST(1 AS bit), '2016-09-08 00:00:00.000', 1019, 1, 20),
(3381, 5, CAST(0 AS bit), '2016-09-08 00:00:00.000', 1020, 1, 16),
(3382, 5, CAST(1 AS bit), '2016-09-08 00:00:00.000', 1020, 1, 54)
) T(Id, SiteId, IsNormal, DateReview, ObjectId, FrequencyId, InspectionId)
)
SELECT Id, SiteId, IsNormal, DateReview, ObjectId, FrequencyId, InspectionId
FROM
(
SELECT ObjectId, MIN(SiteId) SiteId,
CONVERT(bit, MIN(CONVERT(int, IsNormal))) IsNormal,
MIN(DateReview) DateReview, MIN(FrequencyId) FrequencyId
FROM Src
GROUP BY ObjectId
) Dist
CROSS APPLY
(
SELECT STUFF((SELECT ','+CONVERT(varchar(10),Id)
FROM Src
WHERE ObjectId=Dist.ObjectId
FOR XML PATH('')), 1, 1, '')
) Ids(Id)
CROSS APPLY
(
SELECT STUFF((SELECT ','+CONVERT(varchar(10),InspectionId)
FROM Src
WHERE ObjectId=Dist.ObjectId
FOR XML PATH('')), 1, 1, '')
) InspectionIds(InspectionId)
您可以使用以下命令:
WITH Src AS
(
SELECT * FROM (VALUES
(3379, 5, CAST(1 AS bit), '2016-09-08 00:00:00.000', 1019, 1, 16),
(3380, 5, CAST(1 AS bit), '2016-09-08 00:00:00.000', 1019, 1, 20),
(3381, 5, CAST(0 AS bit), '2016-09-08 00:00:00.000', 1020, 1, 16),
(3382, 5, CAST(1 AS bit), '2016-09-08 00:00:00.000', 1020, 1, 54)
) T(Id, SiteId, IsNormal, DateReview, ObjectId, FrequencyId, InspectionId)
)
SELECT Id, SiteId, IsNormal, DateReview, ObjectId, FrequencyId, InspectionId
FROM
(
SELECT ObjectId, MIN(SiteId) SiteId,
CONVERT(bit, MIN(CONVERT(int, IsNormal))) IsNormal,
MIN(DateReview) DateReview, MIN(FrequencyId) FrequencyId
FROM Src
GROUP BY ObjectId
) Dist
CROSS APPLY
(
SELECT STUFF((SELECT ','+CONVERT(varchar(10),Id)
FROM Src
WHERE ObjectId=Dist.ObjectId
FOR XML PATH('')), 1, 1, '')
) Ids(Id)
CROSS APPLY
(
SELECT STUFF((SELECT ','+CONVERT(varchar(10),InspectionId)
FROM Src
WHERE ObjectId=Dist.ObjectId
FOR XML PATH('')), 1, 1, '')
) InspectionIds(InspectionId)
为什么在
ObjectId=1020
的情况下,您希望Id=3382
并且IsNormal=False
?这些数据来自不同的行。。。。是不是Id=3381
?@msanz,我更新了我的问题,这是个错误,你能看一下吗。你尝试过解决方案吗?@Tanner我试图在objectId上创建group by,但它不起作用,我得到了一个错误,它要求聚合函数。但是我对这个问题不太熟悉。@Michael:试试我的答案。为什么在ObjectId=1020
的情况下,您希望Id=3382
并且IsNormal=False
?这些数据来自不同的行。。。。是不是Id=3381
?@msanz,我更新了我的问题,这是个错误,你能看一下吗。你尝试过解决方案吗?@Tanner我试图在objectId上创建group by,但它不起作用,我得到了一个错误,它要求聚合函数。但是我对这个问题不熟悉。@Michael:试试我的答案。谢谢你的帮助。但是我在我的问题上犯了一些错误,如果是位列而不是字符串,则为IsNormal列。你能看到我的更新吗?谢谢你的帮助。但是我在我的问题上犯了一些错误,如果是位列而不是字符串,则为IsNormal列。你能看到我的更新吗修正。嗨,帕维尔。有没有办法加快上面的查询速度?交叉应用需要花费大量的时间。示例已修复。嗨,Pawel。有没有办法加快上面的查询速度?交叉应用需要大量的时间。