SQL 服务器查询 - 使用 Union All 中的 Order By 对数据进行排序
SQL Server Query - Sorting data using Order By in Union All
这是示例数据,此 table 汇总了一位租户在 5 年内每月的销售额。此外,还会计算总销售额、每月和每天的平均销售额。为了能够做到这一点,我使用了 4 sql 查询来获取
- 每月和每年的销售额,
- 总销售额,
- 每月平均销售额,
- 每天的平均销售额
然后,我使用 UNION ALL 方法产生了这种输出:
这是部分代码
SELECT tenantcode, MONTH, year1, year2, year3, year4, year5
from #SalesPerYear
UNION ALL
SELECT * FROM #TotalSales
UNION ALL
SELECT * FROM #AveSalesMonth
UNION ALL
SELECT * FROM #AveSalesDay
ORDER BY TENANTCODE
每个temptable对应每个query得到上面提到的每个query集
但这只会在单个租户中产生输出,我想要的是通过选择多个租户来使其灵活,我能够做到,但排序并不令人满意。 期望的输出是这样的
但实际输出未实现。 Tenant1 排序没问题,但 tenant2 乱七八糟。
关于这个
我希望我解释得足够好。
您可以在标识行类型(每年、总计、月平均和日平均2)的所有查询中添加一个假列。然后按租户、行类型和月份编号对组合结果进行排序,顺序为:
SELECT 1 AS [row type], tenantcode, [month], year1, year2, year3, year4, year5 FROM #SalesPerYear
UNION ALL
SELECT 2, #TotalSales.* FROM #TotalSales
UNION ALL
SELECT 3, #AveSalesMonth.* FROM #AveSalesMonth
UNION ALL
SELECT 4, #AveSalesDay.* FROM #AveSalesDay
ORDER BY tenantcode, [row type], [month]
您可以使用 DATEPART(MONTH, 'January 1, 2000')
将月份名称转换为数字,或使用 DATENAME(MONTH, '2000-1-1')
将月份名称转换为名称。
替代解决方案
由于结果应按以下顺序按月份列排序:JAUNARY、...、DECEMBER、TOTAL、AVE/MONTH、AVE/DAY。您可以简单地使用嵌套查询和冗长的 CASE
语句:
SELECT * FROM (
SELECT tenantcode, [month], year1, year2, year3, year4, year5 FROM #SalesPerYear UNION ALL
SELECT * FROM #TotalSales UNION ALL
SELECT * FROM #AveSalesMonth UNION ALL
SELECT * FROM #AveSalesDay
) AS foobar
ORDER BY tenantcode, CASE [month]
WHEN 'JANUARY' THEN 1
WHEN 'FEBRUARY' THEN 2
WHEN 'MARCH' THEN 3
WHEN 'APRIL' THEN 4
WHEN 'MAY' THEN 5
WHEN 'JUNE' THEN 6
WHEN 'JULY' THEN 7
WHEN 'AUGUST' THEN 8
WHEN 'SEPTEMBER' THEN 9
WHEN 'OCTOBER' THEN 10
WHEN 'NOVEMBER' THEN 11
WHEN 'DECEMBER' THEN 12
END
有几种方法可以简化 case 语句,但我宁愿保持它的可读性。
你能试试这个吗
select * from
(
SELECT tenantcode, MONTH, year1, year2, year3, year4, year5
from #SalesPerYear
UNION ALL
SELECT * FROM #TotalSales
UNION ALL
SELECT * FROM #AveSalesMonth
UNION ALL
SELECT * FROM #AveSalesDay
)t
ORDER BY TENANTCODE
这是示例数据,此 table 汇总了一位租户在 5 年内每月的销售额。此外,还会计算总销售额、每月和每天的平均销售额。为了能够做到这一点,我使用了 4 sql 查询来获取
- 每月和每年的销售额,
- 总销售额,
- 每月平均销售额,
- 每天的平均销售额
然后,我使用 UNION ALL 方法产生了这种输出:
这是部分代码
SELECT tenantcode, MONTH, year1, year2, year3, year4, year5
from #SalesPerYear
UNION ALL
SELECT * FROM #TotalSales
UNION ALL
SELECT * FROM #AveSalesMonth
UNION ALL
SELECT * FROM #AveSalesDay
ORDER BY TENANTCODE
每个temptable对应每个query得到上面提到的每个query集
但这只会在单个租户中产生输出,我想要的是通过选择多个租户来使其灵活,我能够做到,但排序并不令人满意。 期望的输出是这样的
但实际输出未实现。 Tenant1 排序没问题,但 tenant2 乱七八糟。
关于这个
我希望我解释得足够好。
您可以在标识行类型(每年、总计、月平均和日平均2)的所有查询中添加一个假列。然后按租户、行类型和月份编号对组合结果进行排序,顺序为:
SELECT 1 AS [row type], tenantcode, [month], year1, year2, year3, year4, year5 FROM #SalesPerYear
UNION ALL
SELECT 2, #TotalSales.* FROM #TotalSales
UNION ALL
SELECT 3, #AveSalesMonth.* FROM #AveSalesMonth
UNION ALL
SELECT 4, #AveSalesDay.* FROM #AveSalesDay
ORDER BY tenantcode, [row type], [month]
您可以使用 DATEPART(MONTH, 'January 1, 2000')
将月份名称转换为数字,或使用 DATENAME(MONTH, '2000-1-1')
将月份名称转换为名称。
替代解决方案
由于结果应按以下顺序按月份列排序:JAUNARY、...、DECEMBER、TOTAL、AVE/MONTH、AVE/DAY。您可以简单地使用嵌套查询和冗长的 CASE
语句:
SELECT * FROM (
SELECT tenantcode, [month], year1, year2, year3, year4, year5 FROM #SalesPerYear UNION ALL
SELECT * FROM #TotalSales UNION ALL
SELECT * FROM #AveSalesMonth UNION ALL
SELECT * FROM #AveSalesDay
) AS foobar
ORDER BY tenantcode, CASE [month]
WHEN 'JANUARY' THEN 1
WHEN 'FEBRUARY' THEN 2
WHEN 'MARCH' THEN 3
WHEN 'APRIL' THEN 4
WHEN 'MAY' THEN 5
WHEN 'JUNE' THEN 6
WHEN 'JULY' THEN 7
WHEN 'AUGUST' THEN 8
WHEN 'SEPTEMBER' THEN 9
WHEN 'OCTOBER' THEN 10
WHEN 'NOVEMBER' THEN 11
WHEN 'DECEMBER' THEN 12
END
有几种方法可以简化 case 语句,但我宁愿保持它的可读性。
你能试试这个吗
select * from
(
SELECT tenantcode, MONTH, year1, year2, year3, year4, year5
from #SalesPerYear
UNION ALL
SELECT * FROM #TotalSales
UNION ALL
SELECT * FROM #AveSalesMonth
UNION ALL
SELECT * FROM #AveSalesDay
)t
ORDER BY TENANTCODE