Sql server 如何按ObjectId对表进行分组?

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-

我对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-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。有没有办法加快上面的查询速度?交叉应用需要大量的时间。