2013-07-26 88 views
-1

我试图获取患者部门和月份明智的报告。我正在选择一个部门和这个月份。我怎样才能明智地获得选定的月份记录部门。我想下面的查询,但不工作:根据所选月份从表格中获取月份

SELECT MONTH(select convert(varchar,creation_Date,105) from Patient_Ref_master) 
+0

@BogdanSahlean:只有月的行 – Ankur

+0

什么是一个月:1968年8月或8月? – HABO

+0

请注意[已接受的答案](http://stackoverflow.com/a/17887727/61305)如果您目前(或将要)在'creation_Date'列上有索引,则效率非常低。一旦你有超过一年的数据,它也不会像你认为它的工作方式那样工作。一个开放式的范围,[如Habo的答案](http://stackoverflow.com/a/17888631/61305)将会更好地工作(即使接受的答案添加了YEAR()过滤器)。 –

回答

-2
select * from Patient_Ref_master 
where MONTH(creation_Date)=1 --target month here, JAN as example 

SQLFIDDLE
此外,我发现similar question在那里你可以得到这个线程额外的解决方法以及other answer

+2

对列应用MONTH()意味着永远不会使用索引搜索。还假定我们想要2000年1月,2001年1月,2002年1月等,而不是特定年份的1月份。 –

4

如果你想单月/年对下面的查询将工作:

select * 
    from Patient_Ref_Master 
    where Cast('20130801' as Date) <= Creation_Date and Creation_Date < Cast('20130901' as Date) 

它查询可以使用索引,因为它并不需要在每一行进行计算的优势。

在查询之前计算限制通常是有帮助的,例如,当月:

declare @Start as Date = DateAdd(month, DateDiff(month, 0, GetDate()), 0); 
declare @End as Date = DateAdd(month, 1, @Start); 
select * 
    from Patient_Ref_Master 
    where @Start <= Creation_Date and Creation_Date < @End 

编辑:如果使用比较操作的布尔运算符放在一起不管三七二十一是压倒性的,我提供以下简化:

declare @Patient_Ref_Master as Table (Id Int Identity, Creation_Date Date); 
insert into @Patient_Ref_Master (Creation_Date) values 
    ('20130731'), ('20130801'), ('20130815'), ('20130831'), ('20130901'); 
select * from @Patient_Ref_Master; 

declare @Start as Date = DateAdd(month, DateDiff(month, 0, Cast('20130829' as Date)), 0); 
declare @End as Date = DateAdd(month, 1, @Start); 

-- Incomprehensible WHERE clause: 
select * 
    from @Patient_Ref_Master 
    where @Start <= Creation_Date and Creation_Date < @End; 

-- Simplified AB version: 
with 
    JustRight as (
    select * 
     from @Patient_Ref_Master 
     where Creation_Date in (@Start)), 
    NotTooLate as (
    select * 
     from @Patient_Ref_Master 
     where Sign(DateDiff(day, @End, Creation_Date)) in (-1)), 
    NotTooSoon as (
    select * 
     from @Patient_Ref_Master 
     -- NB: Do NOT include zero in the set of matches. That would be too easy. 
     where Sign(DateDiff(day, Creation_Date, @Start)) in (-1)), 
    TheResult as (
    select * 
     from JustRight 
    union 
    select * 
     from NotTooLate 
    intersect 
    select * 
     from NotTooSoon) 
    select * from TheResult; 

没有,IN不在documentation中列为比较运算符

+1

+1,但这是一个奇怪的方式来构造你的子句 - 变量<=列和列<变量。是不是列> =变量和列<变量更符合逻辑?我最初认为你有倒置的运营商。 –

+0

@AaronBertrand - 当有人看到“BETWEEN”与所有东西,某种日期/时间数据一起使用时,曾经有过适合的人。我发现这是写出“之间”相关逻辑的合理清晰的方式,特别是在处理混合开放/关闭时间间隔时。坦率地说,我不能从倒过来的那一个中辨别出一个正确的方向。 – HABO

+1

(1)我根本不提议“BETWEEN” - [我讨厌日期范围查询的BETWEEN](http://sqlblog.com/blogs/aaron_bertrand/archive/2011/10/19/what-do -between和最魔鬼具有功能于common.aspx)。但是通常我们在左侧有列,在右侧有比较器,例如'Creation_Date> = @Start AND Creation_Date <@ End'。我没有看到你经常使用的表格(并且没有发现它非常合乎逻辑),所以我问。 (2)我想你知道我倒过来的意思。 –