2011-02-02 354 views
1

我有一个表中的201101为2011年1月,为201102 2011年2月的形式accounting_period等
我试图总结本季度的一列(eff_cc)。也就是说,我想要得到1月份的数据,2011年3月的第一季度的日期等数据。SQL Case语句的where子句

因此,我在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 
+3

**什么**数据库,哪个版本?? – 2011-02-02 22:03:42

+0

什么不行?你是否收到错误或无效的数据? – 2011-02-02 22:05:45

+0

我不明白,为什么你要与`GETDATE()`比较,输出取决于今天的日期?......你不是只想为每个日期的排序器加总和(eff_cc)存储在你的桌子上? – Lamak 2011-02-02 22:08:44

回答

0

试试这个(我假设它的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 
0

这不是写一个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 
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 
1

感谢大家的提示和USEF ul响应(没有居高临下)

我有点根据您的意见设计了一个解决方案。实质上,我创建了一个包含相关数据的子查询和一个新列(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 

也许这是低效的,但我一周的时间,这一次,所以表现不是一个大问题。 再次感谢所有。