WHERE子句中的SQL CASE使用参数

时间:2014-02-10 01:38:32

标签: sql sql-server tsql ssms

我的Date表中有4个日期列,我想编写一个查询,根据该用户作为参数传递,将触及其中一列: 这是我的代码的一部分:

Select ...
FROM...
WHERE
CASE 
WHEN @timePeriod =  'Cal' THEN d.CalendarYear  = @year 
WHEN @timePeriod =  'Fin' THEN d.FinancialYear = @year 
WHEN @timePeriod =  'Mar' THEN d.YearEndedMarch = @year 
WHEN @timePeriod =  'Sep' THEN d.YearEndedSep = @year 
END

因此用户将提供一个TimePeriod,例如'Fin'和实际年份'2013财年 - 2014年'。 因此,如果用户提供@timePeriod ='Fin',我希望查询按@year过滤Date表。

以下是我想要获得的样本: 我在“数据”列中有一些数据,然后我希望查询按照这4个日历列之一过滤结果。

enter image description here

4 个答案:

答案 0 :(得分:3)

如果没有CASE语句并使用简单的逻辑,您可以这样做:

Select ...
FROM...
WHERE
    (@timePeriod =  'Cal' AND d.CalendarYear  = @year)
OR  (@timePeriod =  'Fin' AND d.FinancialYear = @year) 
OR  (@timePeriod =  'Mar' AND d.YearEndedMarch = @year) 
OR  (@timePeriod =  'Sep' AND d.YearEndedSep = @year) 

[鉴于所有这些列的基数非常相似(或相同),您不必担心参数嗅探缓存不适当的查询计划。]

答案 1 :(得分:2)

另一种变化:

Select ...
FROM...
WHERE @year = 
  CASE 
     WHEN @timePeriod =  'Cal' THEN d.CalendarYear
     WHEN @timePeriod =  'Fin' THEN d.FinancialYear
     WHEN @timePeriod =  'Mar' THEN d.YearEndedMarch
     WHEN @timePeriod =  'Sep' THEN d.YearEndedSep
  END

这一个,可能比使用CASEOR的人更快:

 Select ...
 FROM...
 WHERE  @timePeriod = 'Cal' and d.CalendarYear = @year
 UNION ALL
 Select ...
 FROM ....
 WHERE  @timePeriod = 'Fin' and d.FinancialYear = @year
 UNION ALL
 ... etc...

第二个背后的想法是每个SELECT非常简单并且可以利用您可能拥有的任何索引,而UNION ALL组合它们而不试图过滤掉重复项。由于@timePeriod一次只能有一个值,因此3个查询不会返回任何记录,并且不需要删除任何重复项。

答案 2 :(得分:0)

使用子查询:

  Select ...
  FROM
  (
  SELECT
  CASE 
  WHEN @timePeriod =  'Cal' THEN d.CalendarYear
  WHEN @timePeriod =  'Fin' THEN d.FinancialYear
  WHEN @timePeriod =  'Mar' THEN d.YearEndedMarch
  WHEN @timePeriod =  'Sep' THEN d.YearEndedSep
  END as date
  FROM...) t
  WHERE t.date = @year

答案 3 :(得分:0)

您好我们可以通过在Subquery中使用Union all来更快地进行查询我只是给出了语法示例,因为没有数据可用性

 Select t.TimePeriod,t.CalendarYear
  FROM
  (
  SELECT TIMEID,
   @timePeriod =  'Cal' FROM @x where  t.CalendarYear = @year
   UNION ALL
  SELECT TIMEID,
   @timePeriod =  'FIN' FROM @x where  t.CalendarYear = @year
    UNION ALL
  SELECT TIMEID,
   @timePeriod =  'MAR' FROM @x where  t.CalendarYear = @year
    UNION ALL
  SELECT TIMEID,
   @timePeriod =  'Sep' FROM @x where  t.CalendarYear = @year

) t
  WHERE t.date = @year