2016-02-23 170 views
1

我需要查询表中所有日期中存在的占用空间。Sql查询过滤器

我的表中的数据是

----------------------------------- 
|Room No | Date   | Type | 
----------------------------------- 
|1  | 1 JAN 2016 | AC  | 
|2  | 1 JAN 2016 | AC  | 
|3  | 1 JAN 2016 | Non AC | 
|1  | 2 JAN 2016 | AC  | 
|3  | 2 JAN 2016 | AC  | 
|1  | 3 JAN 2016 | AC  | 
|2  | 3 JAN 2016 | AC  | 
|3  | 3 JAN 2016 | Non AC | 

现在我想要的结果就像

------------------------ 
| RoomNo | Type | 
------------------------ 
| 1   | AC  | 
| 3   | NON AC | 

见上面的例子房间里没有2,所以它不是必需的不存在的1月2日要解决这个问题

+1

学校分配?你有什么尝试? (也许是“GROUP BY”?) – jarlh

+0

使用'GROUP BY Type' no? – simon

+0

什么组通过它不会检查所有的日期目前 –

回答

1

一种方法是比较独特的日期的房间都有独特的日期总数的数量:

SELECT room_no, type 
FROM  (SELECT room_no, type, COUNT(DISTINCT date) AS cnt 
      FROM  rooms 
      GROUP BY room_no, type) r 
JOIN  (SELECT COUNT(DISTINCT date) AS cnt 
      FROM rooms) c ON r.cnt = c.cnt 
+0

我可以从您的查询得到答案,但请你能解释它我无法理解 –

+0

第一个查询(别名为“r”)返回每个房间的不同数量的日期。第二个查询(别名为'c')返回表中不同数量的日期。如果它们相等(加入条件),则表示房间在表中每天都被占用。 – Mureinik

1

的方法有很多,因为它代表的岛屿和差距问题,假设你有三个房间,你只是想给一些值,如果有差距

select row_number() ovver (partition by date order by roomno) as rn, 
roomno,type 
from 
yourtable 
现在

,你可以选择是使用预订

with cte 
    as 
    (
    select row_number() ovver (partition by date order by roomno) as rn, 
     roomno,type 
     from 
     yourtable 
    ) 
select * from cte where rn=3 
012每一天的所有客房个

没有预订房间使用

 with cte 
     as 
     (
     select row_number() ovver (partition by date order by roomno) as rn, 
      roomno,type 
      from 
      yourtable 
     ) 


    select * from cte where rn<3 
+0

这个查询只有在有3个日期时才有效?如果有3个以上的日期?例如日期是2016年1月1日1,2,3,4,5? – Mark

+0

不,我只是举一个例子,我会得到60或90日期 –

+0

请更新您的问题是具体的 – TheGameiswar

1
/* 
My Sql Server Version:Microsoft SQL Server 2012 
The code below can run at above 2005 
*/ 
--Step1:Initialize DataTable 
select * from (VALUES(1,cast('1 JAN 2016' as Date),'AC') 
        ,(2,cast('1 JAN 2016'as Date),'AC') 
        ,(3,cast('1 JAN 2016'as Date),'Non AC') 
        ,(1,cast('2 JAN 2016'as Date),'AC') 
        ,(3,cast('2 JAN 2016'as Date),'AC') 
        ,(1,cast('3 JAN 2016'as Date),'AC') 
        ,(2,cast('3 JAN 2016'as Date),'AC') 
        ,(3,cast('3 JAN 2016'as Date),'Non AC') 
        ) as a(RoomNo,Date,Type) 
-- result 
/* 
RoomNo  Date  Type 
----------- ---------- ------ 
1   1 JAN 2016 AC 
2   1 JAN 2016 AC 
3   1 JAN 2016 Non AC 
1   2 JAN 2016 AC 
3   2 JAN 2016 AC 
1   3 JAN 2016 AC 
2   3 JAN 2016 AC 
3   3 JAN 2016 Non AC 

(8 row(s) affected) 

*/ 
--Step2: The Result 
--Solution A: 
;with FilterResult as (
select RoomNo,Type,Row_Number() over(partition by RoomNo order by Date) as rn 
from (VALUES(1,cast('1 JAN 2016' as Date),'AC') 
        ,(2,cast('1 JAN 2016'as Date),'AC') 
        ,(3,cast('1 JAN 2016'as Date),'Non AC') 
        ,(1,cast('2 JAN 2016'as Date),'AC') 
        ,(3,cast('2 JAN 2016'as Date),'AC') 
        ,(1,cast('3 JAN 2016'as Date),'AC') 
        ,(2,cast('3 JAN 2016'as Date),'AC') 
        ,(3,cast('3 JAN 2016'as Date),'Non AC') 
        ) as a(RoomNo,Date,Type) 
) 
select RoomNo,Type 
from FilterResult 
where rn = 3 
--result 
/* 
RoomNo  Type 
----------- ------ 
1   AC 
3   Non AC 

(2 row(s) affected) 
*/      
--Solution B: 
;with SourceTable as(
select * from (VALUES(1,'1 JAN 2016','AC') 
        ,(2,'1 JAN 2016','AC') 
        ,(3,'1 JAN 2016','Non AC') 
        ,(1,'2 JAN 2016','AC') 
        ,(3,'2 JAN 2016','AC') 
        ,(1,'3 JAN 2016','AC') 
        ,(2,'3 JAN 2016','AC') 
        ,(3,'3 JAN 2016','Non AC') 
        ) as a(RoomNo,Date,Type) 
), 
FilterResult as (
select RoomNo,max(Date) as Date from SourceTable 
group by RoomNo 
having count(Date) =3 
) 
select a.RoomNo,b.Type 
from FilterResult as a inner join SourceTable as b on a.RoomNo = b.RoomNo and a.Date = b.Date 
--Result 
/* 
RoomNo  Type 
----------- ------ 
1   AC 
3   Non AC 

(2 row(s) affected) 
*/