【问题标题】:SQL Case Statement in Where ClauseWhere 子句中的 SQL 案例语句
【发布时间】:2011-02-02 22:02:12
【问题描述】:

我有一个带有accounting_period 的表格,2011 年 1 月的 201101,2011 年 2 月的 201102 等。
我正在尝试对本季度的列 (eff_cc) 求和。也就是说,我想获取 2011 年 1 月、2 月和 3 月第一季度某个日期的数据总和,等等。

所以,我在 where 子句中使用了 Case 语句。基本上我说(在 where 子句中):

  • 如果当前月份是1、4、7或10,则获取该月份的数据;
  • 如果当前月份是2、5、8或11,则获取当前月份和上个月的数据;和
  • 如果当前月份是 3、6、9 或 12,则获取当前和前两个月的数据

不想工作。代码如下。

select phase_code, accounting_period, sum(eff_cc) as BD_Eff_QTD, 
from prj_detail
where 
    case month(getdate()) % 3
        when  1 then    -- current month is 1,4,7,10
            accounting_period = right(Year(getDate()),4) + Right('0' + rtrim(month(getDate())),2)
        when 2 then     -- current month is 2, 5, 8, 11
            (accounting_period = right(Year(getDate()),4) + Right('0' + rtrim(month(getDate())),2) or 
            accounting_period = right(Year(getDate()),4) + Right('0' + rtrim(month(getDate())-1),2))
        when 3 then     -- current month is 3, 6, 9, 12
            (accounting_period = right(Year(getDate()),4) + Right('0' + rtrim(month(getDate())),2) or 
            accounting_period = right(Year(getDate()),4) + Right('0' + rtrim(month(getDate())-1),2) or
            accounting_period = right(Year(getDate()),4) + Right('0' + rtrim(month(getDate())-2),2))
    end
group by phase_code, accounting_period

【问题讨论】:

  • WHAT 数据库,哪个版本??
  • 什么不起作用?您是否收到错误或无效数据?
  • 我不明白,你为什么要和GETDATE()比较?,输出取决于今天的日期?...你不只是想sum(eff_cc)为每个季度存储在您的餐桌上的日期?
  • 错误是“=”附近的语法不正确。基本上,我试图只获取季度至今的信息,而不是每个季度的信息。
  • @R Dev - 所以如果是 2 月,你想要 2 个月的结果,1 月、2 月的每个月一个吗?

标签: sql sql-server case where


【解决方案1】:

您可以为此使用 CTE:

(我还假设所有条目都使用交易日期而不是 getdate())

CREATE TABLE prj_detail
(phase_code VARCHAR(10)
, transaction_date DATETIME
, eff_cc INT)

INSERT INTO prj_detail
SELECT 'c',GETDATE(),11000
UNION ALL SELECT 'a',GETDATE(),1100
UNION ALL SELECT 'b','01/01/2010',2100
UNION ALL SELECT 'c','01/01/2009',500
UNION ALL SELECT 'a','05/01/2010',7800
UNION ALL SELECT 'b','07/01/2008',6000


WITH PhaseCode (phase_code, accounting_period, eff_cc)

AS 

(SELECT phase_code
,  case month(transaction_date) % 3
        when 1 then    -- current month is 1,4,7,10
            right(Year(transaction_date),4) + Right('0' + rtrim(month(transaction_date)),2)
        when 2 then     -- current month is 2, 5, 8, 11
            right(Year(transaction_date),4) + Right('0' + rtrim(month(transaction_date)-1),2)
        when 3 then     -- current month is 3, 6, 9, 12
            right(Year(transaction_date),4) + Right('0' + rtrim(month(transaction_date)-2),2)
    END accounting_period
, eff_cc
from prj_detail)

SELECT phase_code, accounting_period, SUM(eff_cc) AS BD_Eff_QTD
FROM PhaseCode
GROUP BY phase_code, accounting_period

插入行几次后的结果:

phase_code  accounting_period   BD_Eff_QTD
b   200807  12000
c   200901  1000
b   201001  4200
a   201004  15600
a   201101  13200
c   201101  11000

【讨论】:

    【解决方案2】:

    感谢大家的及时和有用的回复(不要居高临下)

    我根据您的意见设计了一个解决方案。本质上,我创建了一个子查询,其中包含相关数据和一个新列 (Qtr)。此列评估 accounting_period,并为每一行分配 1、2、3 或 4。
    然后,我围绕这个子查询包装了另一个选择,使用 where 子句将“Qtr”与当前季度进行比较(来自 getDate)

    select phase_code, sum(BD_Eff_QTD) as BD_Eff_QTD
    from 
    (
    select phase_code, accounting_period, sum(eff_pc) as BD_Eff_QTD,
    'Qtr' = 
    case
    when cast (substring(convert(varchar, accounting_period),5,2) as int) <= 3 then 1
    when cast (substring(convert(varchar, accounting_period),5,2) as int) <= 6 then 2
    when cast (substring(convert(varchar, accounting_period),5,2) as int) <=9 then 3
    else 4
    end
    from prj_detail
    group by phase_code, accounting_period
    ) X
    where CurQtr = datepart(qq,getDate()) 
    group by phase_code
    

    也许这效率低下,但我每周只运行一次,所以性能不是大问题。 再次感谢大家。

    【讨论】:

      【解决方案3】:

      这不是编写 CASE 语句的正确方法,因为它返回一个 BOOLEAN,在 SQL Server 中不能单独存在。只需将它们分成 3 个 OR 子句

      select phase_code, accounting_period, sum(eff_cc) as BD_Eff_QTD
      from prj_detail
      where 
      (    month(getdate()) % 3 = 1 AND -- current month is 1,4,7,10
          accounting_period = right(Year(getDate()),4) + Right('0' + rtrim(month(getDate())),2))
          OR
      (    month(getdate()) % 3 = 2 AND -- current month is 2, 5, 8, 11
          (accounting_period = right(Year(getDate()),4) + Right('0' + rtrim(month(getDate())),2) or 
          accounting_period = right(Year(getDate()),4) + Right('0' + rtrim(month(getDate())-1),2)))
          OR
      (    month(getdate()) % 3 = 2 AND -- current month is 3, 6, 9, 12
          (accounting_period = right(Year(getDate()),4) + Right('0' + rtrim(month(getDate())),2) or 
          accounting_period = right(Year(getDate()),4) + Right('0' + rtrim(month(getDate())-1),2) or
          accounting_period = right(Year(getDate()),4) + Right('0' + rtrim(month(getDate())-2),2)))
      group by phase_code, accounting_period
      

      【讨论】:

      • 我也想过这样的事情,但 OP 回答说他想要的是本季度,而不是每个季度。
      • @Lamak - 在重新阅读问题一段时间后,它点击了
      • 谢谢,就是这样。我正在寻找当前季度的季度至今数据。
      【解决方案4】:

      试试这个(我假设它的 SQL Server):

      SELECT phase_code, 
             accounting_period, 
             SUM(eff_cc) OVER(PARTITION BY phase_code, yr, qt )AS bd_eff_qtd
        FROM   (SELECT a.*, 
                       CAST(Substring(accounting_period, 1, 4) AS INT)     yr, 
                       (CAST(Substring(accounting_period, 5, 2) AS INT) - 1)/ 3 qt 
                FROM   prj_detail a) a 
      

      例如:

      CREATE TABLE #prj_detail
      (
       phase_code VARCHAR(10),
       accounting_period  VARCHAR(10),
       eff_cc INT
      )
      INSERT INTO #prj_detail
      SELECT '1', '201101', 1
      UNION
      SELECT '1', '201102', 2
      UNION
      SELECT '1', '201103', 2
      UNION
      SELECT '1', '201104', 1
      UNION
      SELECT '1', '201105', 1
      UNION
      SELECT '1', '201106', 1
      UNION
      SELECT '1', '201107', 3
      
      
      SELECT phase_code, 
             accounting_period, 
             SUM(eff_cc) OVER(PARTITION BY phase_code, yr, qt )AS bd_eff_qtd
        FROM   (SELECT a.*, 
                       CAST(Substring(accounting_period, 1, 4) AS INT)     yr, 
                       (CAST(Substring(accounting_period, 5, 2) AS INT) - 1)/ 3 qt 
                FROM   #prj_detail a) a 
      

      【讨论】:

      • 你能发布 DDl 和示例数据吗?
      • 不知道 DDI 是什么。样本数据:Phase_Code、accounting_period、eff_cc ---------- ----- ----- AAMC 201101 25.32 AAMC 201102 13.35 AAMC 201104 15.65 ATT 201101 25.00 所以对于上述数据集,结果应该是:AAMC 38.67 (= 25.32 + 13.35),因为我们在第一季度 ATT 25.00
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-14
      • 2010-12-05
      • 1970-01-01
      相关资源
      最近更新 更多