选择带有分组的前1名

时间:2009-11-24 21:32:18

标签: sql-server

我有两列:

namecode name
050125  chris
050125  tof
050125  tof
050130  chris
050131  tof

我想按名称代码进行分组,并仅返回出现次数最多的名称。在这种情况下,结果将是

050125  tof
050130  chris
050131  tof

这是SQL Server 2000

5 个答案:

答案 0 :(得分:10)

我通常使用ROW_NUMBER()来实现这一目标。不确定它如何针对各种数据集执行,但由于使用ROW_NUMBER,我们没有遇到任何性能问题。

PARTITION BY子句指定将行号“分组”的值,ORDER BY子句指定应如何对每个“组”中的记录进行排序。因此,通过NameCode对数据集进行分区,并获取行号为1的所有记录(即每个分区中的第一条记录,按ORDER BY子句排序)。

SELECT 
    i.NameCode, 
    i.Name
FROM 
(
    SELECT 
        RowNumber = ROW_NUMBER() OVER (PARTITION BY t.NameCode ORDER BY t.Name),
        t.NameCode,
        t.Name
    FROM
        MyTable t
) i
WHERE
    i.RowNumber = 1; 

答案 1 :(得分:1)

select distinct namecode
, (
     select top 1 name from 
            (
             select namecode, name, count(*) 
             from myTable i
             where i.namecode = o.namecode
             group by namecode, name 
             order by count(*) desc
            ) x
) as name
from myTable o 

答案 2 :(得分:1)

SELECT max_table.namecode, count_table2.name
FROM
    (SELECT namecode, MAX(count_name) AS max_count
     FROM
         (SELECT namecode, name, COUNT(name) AS count_name
          FROM mytable
          GROUP BY namecode, name) AS count_table1
     GROUP BY namecode) AS max_table
INNER JOIN
    (SELECT namecode, COUNT(name) AS count_name, name
     FROM mytable
     GROUP BY namecode, name) count_table2
ON max_table.namecode = count_table2.namecode AND
   count_table2.count_name = max_table.max_count

答案 3 :(得分:0)

我没有尝试,但这应该有用,

select top 1 t2.* from (
select namecode, count(*) count from temp 
group by namecode) t1 join temp t2 on t1.namecode = t2.namecode 
order by t1.count desc

答案 4 :(得分:0)

以下是您可以使用的示例,但临时表使用比视图更有效,但是在小数据样本上完成。您可以查看自己的统计信息。

    --Creating A View
GO
CREATE VIEW StateStoreSales AS
SELECT t.state,t.stor_id,t.stor_name,SUM(s.qty) 'TotalSales'
,ROW_NUMBER() OVER (PARTITION BY t.state ORDER BY SUM(s.qty) DESC) AS 'Rank'
FROM [dbo].[sales] s
JOIN [dbo].[stores] t ON (s.stor_id = t.stor_id)
GROUP BY t.state,t.stor_id,t.stor_name

GO
SELECT * FROM StateStoreSales
WHERE Rank <= 1
ORDER BY TotalSales Desc

DROP VIEW StateStoreSales


---Using a Temp Table
SELECT t.state,t.stor_id,t.stor_name,SUM(s.qty) 'TotalSales'
,ROW_NUMBER() OVER (PARTITION BY t.state ORDER BY SUM(s.qty) DESC) AS 'Rank'     INTO #TEMP
FROM [dbo].[sales] s
JOIN [dbo].[stores] t ON (s.stor_id = t.stor_id)
GROUP BY t.state,t.stor_id,t.stor_name

SELECT * FROM #TEMP
WHERE Rank <= 1
ORDER BY TotalSales Desc

DROP TABLE #TEMP