在SQL语句中分组

时间:2011-09-17 18:42:22

标签: sql sql-server sql-server-2008

我有以下SQL语句:

    SELECT TOP 30
    a.ClassAdID,    -- 0
    a.AdTitle,      -- 1
    a.ClassAdCatID, -- 2
    b.ClassAdCat,   -- 3
    a.Img1,         -- 4
    e.Domain,       -- 5
    a.AdText,       -- 6
    a.RegionID,     -- 7
    a.IsEvent,      -- 8
    a.IsCoupon,     -- 9
    b.ParentID,     -- 10
    a.MemberID,     -- 11
    a.AdURL,        -- 12
    a.Location,     -- 13
    a.GroupID       -- 14
    FROM ClassAd a
    INNER JOIN ClassAdCat b ON b.ClassAdCatID = a.ClassAdCatID
    INNER JOIN Member d ON d.MemberID = a.MemberID
    INNER JOIN Region e ON e.RegionID = a.RegionID
    WHERE DATEDIFF(d, GETDATE(), a.ExpirationDate) >= 0
    AND PostType <> 'CPN'
    ORDER BY a.CreateDate DESC

我想只显示每个GROUPID中的一个...我如何调整语句来实现这一点,因为我迷失了DISTINCT,GROUP BY等。

任何帮助都将不胜感激。

非常感谢,

3 个答案:

答案 0 :(得分:2)

您可以使用ROW_NUMBER函数根据GroupId值对数据集进行分区,从而:对于每个新的GroupId值,计数器将从1重新启动并且第一行(ROW_NUMBER = 1)是最新记录(a.CreateDate DESC)。然后,我们会过滤所有ROW_NUMBER = 1的记录。

SELECT TOP 30 *
FROM
(
    SELECT
    a.ClassAdID,    -- 0
    a.AdTitle,      -- 1
    a.ClassAdCatID, -- 2
    b.ClassAdCat,   -- 3
    a.Img1,         -- 4
    e.Domain,       -- 5
    a.AdText,       -- 6
    a.RegionID,     -- 7
    a.IsEvent,      -- 8
    a.IsCoupon,     -- 9
    b.ParentID,     -- 10
    a.MemberID,     -- 11
    a.AdURL,        -- 12
    a.Location,     -- 13
    a.GroupID,      -- 14
    ROW_NUMBER() OVER(PARTITION BY a.GroupId ORDER BY a.CreateDate DESC) AS PseudoId
    FROM ClassAd a
    INNER JOIN ClassAdCat b ON b.ClassAdCatID = a.ClassAdCatID
    INNER JOIN Member d ON d.MemberID = a.MemberID
    INNER JOIN Region e ON e.RegionID = a.RegionID
    WHERE DATEDIFF(d, GETDATE(), a.ExpirationDate) >= 0
    AND PostType <> 'CPN'
) q
WHERE q.PseudoId = 1;

答案 1 :(得分:1)

GROUP BY使用AGGREGATE函数...意味着您要将组中的值相加,或者找到组中的最大值或最小值等。

DISTINCT将删除重复的行。

在你的查询中,你可能会得到一堆不太相似的行,所有这些行都碰巧有相同的group_id ......如果是这样,那么你需要决定你真正想要哪一行见。

也许你想要最新的,或者名字最长的那个,或类似的东西。

对于分组,你会选择像createdon这样的列并在选择列表中说出MAX(createdon)之类的内容,然后在选择列表中的每个其他列上分组以找到彼此匹配的行(创建时除外) ,并且只返回一次创建的最大值...希望这是有意义的。

编辑:

组ID和创建日期的非常简单的示例。 (您可以根据需要不断添加更多列 - 在列表中按列表选择一列:

SELECT groupid, max( createdate )
FROM ClassAd
GROUP BY groupId

答案 2 :(得分:0)

如果我理解正确,你想从每个组中获取一行(如groupid)

我使用的是sql server 2005(Nothwind)

SELECT   TOP 30  Customers.CompanyName, Orders.ShipCity, Orders.Freight
FROM         Customers INNER JOIN
                      Orders ON Customers.CustomerID = Orders.CustomerID
GROUP BY Customers.CompanyName, Orders.ShipCity, Orders.Freight