计算SQL中的最大值,最小值和平均值

时间:2011-04-06 18:18:59

标签: sql sql-server

我正在运行下面的脚本。我想知道是否有人知道如何在结果中添加三行:

1.添加MAX值为

的新行

2.添加一个MIN值的新行。

3.添加一个平均值的新行。

这是我的查询,它在2006年4月和5月的两个完整月份运行。

SELECT
DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)) AS FY,
DATENAME(WEEKDAY, SOLD_DATE)              AS DAY,
STORE_NAME                                AS STORE,
CONVERT (VARCHAR, SOLD_DATE, 10)          DATES,
SUM(ITEMS)                                AS ITEM,
'NUMBER'                                  AS NOTE     
FROM MYTABLE
WHERE SOLD_DATE >='04/1/2006'
AND SOLD_DATE <'06/1/2006'
AND STORE_NAME ='ELEVEN'
GROUP BY DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)), 
DATENAME(WEEKDAY, SOLD_DATE), STORE_NAME, SOLD_DATE

查询产生以下结果(部分),结果底部有所需的附加行。

非常感谢, 乔

FY     DAY        STORE   DATES     ITEM    NOTE
2006    Saturday    ELEVEN  4/1/2006    14  NUMBER
2006    Sunday      ELEVEN  4/2/2006    21  NUMBER
2006    Monday      ELEVEN  4/3/2006    24  NUMBER
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
2006    Monday      ELEVEN  5/29/2006   37  NUMBER
2006    Tuesday     ELEVEN  5/30/2006   20  NUMBER
2006    Wednesday   ELEVEN  5/31/2006   25  NUMBER
2006    Saturday    ELEVEN  5/13/2006   5   MINIMUM
2006    Tuesday     ELEVEN  5/16/2006   61  MAXIMUM
2006                ELEVEN              25  AVERAGE

3 个答案:

答案 0 :(得分:2)

建议您先将查询加载到表变量中。然后,您可以执行元操作。然后UNION将3行放到结果集上。

这种方法的好处:

  • 您是从SAME结果集计算的。如果您复制/粘贴3(最小,最大,平均)的查询,则可能可能正在读取不同的数据,如果有另一个进程在您计算时更新了行。如果/当发生这种情况时,与结果集中的原始数据相比,您的计算似乎是不正确的。

  • 更少的代码来阅读和维护

DECLARE @MyResults (TABLE) (FY int, DAY varchar(10), STORE varchar(10),   DATES varchar(10), ITEM varchar(10),    NOTE varchar(10))

DECLARE   @MyCalcs TABLE (ForYear int, Item int, Note varchar(100))

--calc the avg, max and min

INSERT INTO @MyCalcs (ForYear, Item, Note)
   SELECT  FY, AVG(ITEMS), 'Average'
   FROM @MyResults GROUP BY FY

INSERT INTO @MyCalcs (ForYear, Item, Note)
   SELECT  FY, Max(ITEMS), 'Max'
   FROM @MyResults GROUP BY FY

INSERT INTO @MyCalcs (ForYear, Item, Note)
   SELECT  FY, MIN(ITEMS), 'Min'
   FROM @MyResults GROUP BY FY

--union the discrete data with the calcs
SELECT FY,DAY,STORE,DATES,ITEM,NOTE
FROM @MyResults
UNION ALL
SELECT ForYear AS FY, '' AS Day, '' AS Store, Item, Note
FROM @MyCalcs

答案 1 :(得分:1)

SELECT 0 as p,
DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)) AS FY,
DATENAME(WEEKDAY, SOLD_DATE)              AS DAY,
STORE_NAME                                AS STORE,
CONVERT (VARCHAR, SOLD_DATE, 10)          DATES,
SUM(ITEMS)                                AS ITEM,
'NUMBER'                                  AS NOTE     
FROM MYTABLE
WHERE SOLD_DATE >='04/1/2006'
AND SOLD_DATE <'06/1/2006'
AND STORE_NAME ='ELEVEN'
GROUP BY DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)), 
DATENAME(WEEKDAY, SOLD_DATE), STORE_NAME, SOLD_DATE

union

SELECT 1 as p,
DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)) AS FY,
DATENAME(WEEKDAY, SOLD_DATE)              AS DAY,
STORE_NAME                                AS STORE,
CONVERT (VARCHAR, SOLD_DATE, 10)          DATES,
min(ITEMS)                                AS ITEM,
'MINIMUM'                                  AS NOTE     
FROM MYTABLE
WHERE SOLD_DATE >='04/1/2006'
AND SOLD_DATE <'06/1/2006'
AND STORE_NAME ='ELEVEN'
GROUP BY DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)), 
DATENAME(WEEKDAY, SOLD_DATE), STORE_NAME, SOLD_DATE
having items = min(items)
limit 1

union

SELECT 2 as p,
DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)) AS FY,
DATENAME(WEEKDAY, SOLD_DATE)              AS DAY,
STORE_NAME                                AS STORE,
CONVERT (VARCHAR, SOLD_DATE, 10)          DATES,
max(ITEMS)                                AS ITEM,
'MAXIMUM'                                  AS NOTE     
FROM MYTABLE
WHERE SOLD_DATE >='04/1/2006'
AND SOLD_DATE <'06/1/2006'
AND STORE_NAME ='ELEVEN'
GROUP BY DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)), 
DATENAME(WEEKDAY, SOLD_DATE), STORE_NAME, SOLD_DATE
having items = max(items)
limit 1

union

SELECT 3 as p,
DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)) AS FY,
''                                        AS DAY,
STORE_NAME                                AS STORE,
''                                        DATES,
avg(ITEMS)                                AS ITEM,
'AVERAGE'                                 AS NOTE     
FROM MYTABLE
WHERE SOLD_DATE >='04/1/2006'
AND SOLD_DATE <'06/1/2006'
AND STORE_NAME ='ELEVEN'
GROUP BY DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)), 
DATENAME(WEEKDAY, SOLD_DATE), STORE_NAME, SOLD_DATE

order by p

答案 2 :(得分:1)

  • 要将它们放在底部,您需要一个虚拟排序列。
  • 要添加其他行,您需要同时生成多个UNION-ed结果。
  • 每组只占一行,你需要使用TOP,但每个UNION查询只能使用一个TOP,所以你需要对它们进行子查询。
  • 像'04 / 1/2006'这样的日期容易出现错误的DATEFORMAT设置。使用YYYYMMDD,例如20060104获得稳健的结果

在事务(隔离级别快照)中执行此操作,以查看UNION部件之间的一致结果。

SELECT FY, DAY, STORE, DATES, ITEM, NOTE
FROM
(
SELECT Sorter=1,
DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)) AS FY,
DATENAME(WEEKDAY, SOLD_DATE)              AS DAY,
STORE_NAME                                AS STORE,
CONVERT (VARCHAR, SOLD_DATE, 10)          DATES,
SUM(ITEMS)                                AS ITEM,
'NUMBER'                                  AS NOTE     
FROM MYTABLE
WHERE SOLD_DATE >='04/1/2006'
AND SOLD_DATE <'06/1/2006'
AND STORE_NAME ='ELEVEN'
GROUP BY DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)), 
DATENAME(WEEKDAY, SOLD_DATE), STORE_NAME, SOLD_DATE
UNION ALL
SELECT 2,* FROM (
SELECT TOP 1
DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)) AS FY,
DATENAME(WEEKDAY, SOLD_DATE)              AS DAY,
STORE_NAME                                AS STORE,
CONVERT (VARCHAR, SOLD_DATE, 10)          DATES,
SUM(ITEMS)                                AS ITEM,
'MAX'                                  AS NOTE     
FROM MYTABLE
WHERE SOLD_DATE >='04/1/2006'
AND SOLD_DATE <'06/1/2006'
AND STORE_NAME ='ELEVEN'
GROUP BY DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)), 
DATENAME(WEEKDAY, SOLD_DATE), STORE_NAME, SOLD_DATE
ORDER BY ITEM DESC) X
UNION ALL
SELECT 3,* FROM (
SELECT TOP 1
DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)) AS FY,
DATENAME(WEEKDAY, SOLD_DATE)              AS DAY,
STORE_NAME                                AS STORE,
CONVERT (VARCHAR, SOLD_DATE, 10)          DATES,
SUM(ITEMS)                                AS ITEM,
'MIN'                                  AS NOTE     
FROM MYTABLE
WHERE SOLD_DATE >='04/1/2006'
AND SOLD_DATE <'06/1/2006'
AND STORE_NAME ='ELEVEN'
GROUP BY DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)), 
DATENAME(WEEKDAY, SOLD_DATE), STORE_NAME, SOLD_DATE
ORDER BY ITEM) X
UNION ALL
SELECT 4, FY, '', STORE, '', AVG(ITEM), NOTE
FROM (
SELECT
DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)) AS FY,
DATENAME(WEEKDAY, SOLD_DATE)              AS DAY,
STORE_NAME                                AS STORE,
CONVERT (VARCHAR, SOLD_DATE, 10)          DATES,
SUM(ITEMS)                                AS ITEM,
'AVERAGE'                                  AS NOTE     
FROM MYTABLE
WHERE SOLD_DATE >='04/1/2006'
AND SOLD_DATE <'06/1/2006'
AND STORE_NAME ='ELEVEN'
GROUP BY DATEPART(YYYY, DATEADD(MM, 3, SOLD_DATE)), 
DATENAME(WEEKDAY, SOLD_DATE), STORE_NAME, SOLD_DATE) Y
) X
ORDER BY SORTER