在查询sqlserver中获取group by子句的第一行

时间:2011-03-17 17:15:10

标签: .net sql-server

我在数据库中有一个doucments列表,有些属于一个组,有些则不属于。当doucment属于一个组时,我希望Group名称在列表中显示为doucment名称(不是实际的doucment名称 - 请参见case语句)(与所有其他doucments一起)。我希望组名只出现一次(使用第一个doucment的ID) 说我有

Cat    DocName        DocID
---------------------------
3      Doucmnt1         4
3      Document2        5
3      Document Group   6
3      Document Group   7

我想在上面的列表'文档组'中只出现一次ID为6.谢谢!

我有以下查询:

SELECT Docs.DocID, Docs.Category, 
         CASE WHEN Docs.Group IS NULL THEN Docs.DocName 
              ELSE GroupDocs.GroupName 
         END AS DocumentName, Docs.DocID 
    FROM Docs 
        LEFT OUTER JOIN GroupDocs 
            ON Docs.GroupDoc = GroupDocs.GroupID 
    WHERE Docs.DocCategory = @DocCategory

3 个答案:

答案 0 :(得分:3)

如果您使用的是SQL Server 2005或更高版本,则可以使用排名功能:

With NumberedDocs As
    (
    Select Docs.DocId, Docs.Category
        , Coalesce( GroupDocs.GroupName, Docs.DocName ) As Name
        , Row_Number() Over( Partition By Coalesce( GroupDocs.GroupName, Docs.DocName ) Order By Docs.DocId ) As Num
    From Docs
        Left Join GroupDocs
            On GroupDocs.GroupId = Docs.GroupDoc
    Where Docs.DocCategory = @DocCategory
    )
Select DocId, DocCategory, Name
From NumberedDocs
Where Num = 1

答案 1 :(得分:0)

解决方案如何

SELECT  DocID,
        Category,
        DocName,
        CASE WHEN n = 1 THEN GroupName ELSE '' END AS GroupName,
FROM    (
         SELECT Docs.DocID,
                Docs.Category,
                Docs.DocName,
                ISNULL(GroupDocs.GroupName, '') AS GroupName,
                Docs.DocID,
                n = ROW_NUMBER() OVER(PARTITION BY GroupDocs.GroupName
                                      ORDER BY Docs.DocId)
         FROM   Docs
                LEFT OUTER JOIN GroupDocs
                    ON Docs.GroupDoc = GroupDocs.GroupID
         WHERE  (Docs.DocCategory = @DocCategory)
        ) data
ORDER BY data.GroupName, data.DocID

答案 2 :(得分:0)

首先,根据需要准备文档名称替换为组名的文档列表。然后按GroupDocDocID(对于单个文档)或NULL(对于文档组)对结果集进行分组。

以下是:

SELECT
  DocCategory,
  DocumentName,
  DocID = MIN(DocID)
FROM (
  SELECT
    d.DocID,
    d.DocCategory,
    DocumentName = COALESCE(g.GroupName, d.DocName),
    d.GroupDoc
  FROM Docs d
    INNER JOIN GroupDocs g ON d.GroupDoc = g.GroupID
  WHERE d.DocCategory = @DocCategory
) s
GROUP BY
  DocCategory,
  DocumentName,
  GroupDoc,
  CASE WHEN GroupDoc IS NULL THEN DocID END