我有一个包含两列(FileExtension和FileSize)的表,如下所示:
FileType FileSize
---------------------------
dll 129
bak 2323
ext 242424
ini 40
bak 532
log 32
bak 3253
dll 9094
bak 234
txt 587
dll 1000
我尝试编写SQL查询,可能使用ROLLUP或COMPUTE的组合,它将根据最大的FileSize提供FileTypes列中的前3个值。 Total列将包含在报告的底部,提供FileSize列中所有值的总和。查询结果如下:
FileType FileExtension
-------------------------------
ext 242424
dll 10223
bak 6342
Total 259648
对于如何完成此查询的任何想法将不胜感激。谢谢!
答案 0 :(得分:1)
这是基本的分组:
;with cte as (
select top 3 FileType, sum(FileSize) as FileExtension
from TableName
group by FileType
order by FileExtension desc
)
select * from cte
union all
select 'Total', sum(FileExtension) from cte
如果我理解正确:
;with cte as (
select top 3 FileType, sum(FileSize) as FileExtension
from TableName
group by FileType
order by FileExtension desc
)
select * from cte
union all
select 'Total', sum(FileSize) from TableName
答案 1 :(得分:1)
您可以在单个查询中获得每个FileSize
的总FileType
值和总计FileSize
,如下所示:
SELECT
FileType,
TotalSize = SUM(FileSize)
FROM
dbo.YourTable
GROUP BY
ROLLUP(FileType)
;
作为ROLLUP分组功能的结果,您将有一个额外的行,TotalSize
值是所有单个TotalSize
值的总和,FileType
设置为NULL。< / p>
要仅获得前三个总计和总计,您可以按TotalSize
的降序对结果进行排序,并将TOP (4)
添加到SELECT子句中:
SELECT TOP (4)
FileType,
TotalSize = SUM(FileSize)
FROM
dbo.YourTable
GROUP BY
ROLLUP(FileType)
ORDER BY
TotalSize DESC
;
这几乎可以满足您的需求。您只需要将FileType
替换为'Total'
,并将总计行移至结果集的末尾。
第一个问题很简单:只需使用COALESCE
功能即可。要解决第二个问题,您可以将上述查询用作派生表并再次对结果进行排序,如下面的final query所示:
SELECT
FileType = COALESCE(FileType, 'Total'),
TotalSize
FROM
(
SELECT TOP (4)
FileType,
TotalSize = SUM(FileSize)
FROM
dbo.YourTable
GROUP BY
ROLLUP(FileType)
ORDER BY
TotalSize DESC
) AS s
ORDER BY
CASE WHEN FileType IS NULL THEN 1 ELSE 0 END ASC,
TotalSize DESC
;
外部查询的第一个排序标准是一个CASE表达式,对于总计行(基于其FileType
为空的事实)的计算结果为1,并且对于每个其他计算结果为0。该结果的升序确保总行最终位于集合的底部。
请注意,如果FileType
列具有自己的NULL,则如果NULL结果是前三个中的一个,则上述查询将无法正常工作。然后,您需要一种方法来区分来自源数据集的NULL和ROLLUP函数生成的NULL。您可以在此处使用GROUPING函数,
指示是否聚合GROUP BY列表中的指定列表达式。 GROUPING为聚合返回1,为结果集中的未聚合返回0。
因此,如果GROUPING(FileType)
返回1,那将是累积行,否则它将是FileType
小计。函数的结果可以很容易地用'Total'
替换列值并对最终输出的结果进行排序。唯一的问题是,因为该函数仅在GROUP BY查询的直接上下文中有意义,但是对函数的结果进行排序将在稍后阶段执行,您可能需要将这些结果作为列返回派生表的供以后使用。以下rewrite of the previous query显示了具体方式:
SELECT
FileType = CASE IsRollup WHEN 1 THEN 'Total' ELSE FileType END,
TotalSize
FROM
(
SELECT TOP (4)
FileType,
TotalSize = SUM(FileSize),
IsRollup = GROUPING(FileType)
FROM
dbo.YourTable
GROUP BY
ROLLUP(FileType)
ORDER BY
TotalSize DESC
) AS s
ORDER BY
IsRollup ASC,
TotalSize DESC
;