【问题标题】:How to compute column by specific value?如何按特定值计算列?
【发布时间】:2018-09-11 09:19:03
【问题描述】:

如何查询这些图片的结果。 第一列选择是本月加上下一列按条件字段 (SelectColumn)

黄色背景是 sum 的选择列

我的示例代码。

    declare @myDate date = getdate(),@qry varchar(max)

set @qry = 'select case v.SelectColumn
    when 0 then (SELECT '+DATENAME(month,@myDate)+')
    when 2 then (SELECT '+DATENAME(month,@myDate)+'+'+DATENAME(MONTH,DATEADD(MONTH,1,@myDate))+')
    when 1 then (SELECT '+DATENAME(month,@myDate)+'+'+DATENAME(MONTH,DATEADD(MONTH,1,@myDate))+'+'+DATENAME(MONTH,DATEADD(MONTH,2,@myDate))+')

    end
    as SumColumn

from vwQC12Month v'
exec (@qry)

【问题讨论】:

  • 这是一个有趣的问题。不需要大量 CASE 语句的适当解决方案需要使用 UNPIVOT 将月份列旋转成行,然后对其进行聚合。
  • 除了 0,2,1 看似错误的方式(应该是 0,1,2)之外,查询构建和执行正确,那么问题是什么?
  • @P.Salmon 如果情况是 7 或更多。我是否需要添加很多案例结果 (SELECT '+DATENAME(month,@myDate).... 我认为是一种无效的方法
  • 使用您现有的方法,您将不得不添加很多案例语句。在我看来,如果您对它的工作感到满意,它是可维护的,符合您获得的规范和资源并且执行可接受,那么它是一种有效的方法。话虽如此,在确定解决方案之前,我会将您的方法与 unpivot/pivot 方法(我认为更容易理解)进行性能比较。

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


【解决方案1】:

此问题要求每月值可以作为行访问,以便可以应用选定的聚合。通常,您可以使用 UNPIVOT 或 VALUES 将列旋转为行。下面是一个使用 UNPIVOT 的工作示例。

在下面的查询中,您必须更改缩写形式的月份名称以匹配您的列名称才能使其正常工作。这是一个工作演示:http://sqlfiddle.com/#!18/094e4/2

您可能还需要考虑如何处理年终包装并相应地调整聚合。

-- setup sample data 
create table Test (
  id int, Jan int, Feb int, Mar int, Apr int, May int, 
  Jun int, Jul int, Aug int, Sep int, Oct int, Nov int, Dec int,
  SelectColumn int)

insert Test values
(1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 1),
(2, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 2),
(3, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 3),
(4, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 4)

-- query 
DECLARE @currentMonthNumber int = MONTH(getdate())

-- CTE that rotates the data into rows
; WITH RowsByMonth(id, SelectColumn, monthNumber, val) AS
(
  SELECT id, SelectColumn, CONVERT(int, month) AS monthNumber, val
  FROM
    (SELECT id, SelectColumn, 
       Jan AS [1], Feb AS [2], Mar AS [3], Apr AS [4], 
       May AS [5], Jun AS [6], Jul AS [7], Aug AS [8],
       Sep AS [9], Oct AS [10], Nov AS [11], Dec AS [12] 
     FROM Test) AS Source
     UNPIVOT
     (val FOR month IN 
      ([1], [2], [3], [4],
       [5], [6], [7], [8],
       [9], [10], [11], [12])
     ) AS asRows 
) -- aggregation below 
SELECT id, SUM(val) AS SumAcrossSelectedMonths
FROM RowsByMonth
WHERE 
  monthNumber >= @currentMonthNumber 
  AND monthNumber - @currentMonthNumber < SelectColumn
GROUP BY id

-- Results
| id | SumAcrossSelectedMonths |
|----|-------------------------|
|  1 |                      40 |
|  2 |                      90 |
|  3 |                     150 |
|  4 |                     220 |

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-20
    • 2020-07-12
    • 1970-01-01
    • 2020-08-02
    • 1970-01-01
    • 2020-03-07
    • 1970-01-01
    相关资源
    最近更新 更多