我需要获取TABLE_A
中的所有记录,其中至少 2 最后Status
是空的(相对于Inspection_Date
)和{{1} } Room_ID
中不存在。
这是我用作示例的简化表:
TABLE_A :
TABLE_B
表-B :
Room_Id Status Inspection_Date
-------------------------------------
1 vacant 5/15/2015
2 occupied 5/21/2015
2 vacant 1/19/2016
1 occupied 12/16/2015
4 vacant 3/25/2016
3 vacant 8/27/2015
1 vacant 4/17/2016
3 vacant 12/12/2015
3 vacant 3/22/2016
4 occupied 2/2/2015
4 vacant 3/24/2015
我的结果应如下所示:
Room_Id Status Inspection_Date
------------------------------------
1 vacant 5/15/2015
2 occupied 5/21/2015
2 vacant 1/19/2016
1 vacant 12/16/2015
1 vacant 4/17/2016
我试过这种方式,它适用于示例,但不能处理我的数据..逻辑不完整:
Room_Id Status Inspection_Date
---------------------------------
3 vacant 8/27/2015
3 vacant 12/12/2015
3 vacant 3/22/2016
4 occupied 2/2/2015
4 vacant 3/24/2015
4 vacant 3/25/2016
这是架构:
With cteA As
(
Select *, Row_Number() Over (Partition By Room_ID, Status Order By Inspection_Date Desc) RowNum From Table_A
)
Select * From Table_A Where Room_Id In
(
Select Room_Id
From cteA
Where Room_Id Not In (Select Room_Id From Table_B)
And Status = 'vacant' And RowNum > 1
)
Order By Room_Id, Inspection_Date
答案 0 :(得分:1)
<强> PLAIN 强>
对于TABLE_A中的每个房间,选择最后一个日期(作为lastDate)
TABLE_A中的每个房间选择上一个日期(作为prevLastDate)
从lastDate获取room_ids,状态为'vacant'(作为lastDateVacant)
从prevLastDate获取room_ids,其状态为'空置'(as prevLastDateVacant)
过滤TABLE_A只包含lastDateVacant和prevLastDateVacant(内部)中的ID
过滤TABLE_A,使其只有不在TABLE_B中的ID(左外+ IS NULL)
结果你有:
WITH lastDate AS (
SELECT room_id AS room,MAX(inspection_date) AS date
FROM "TABLE_A"
GROUP BY room_id
), prevLastDate AS (
SELECT room_id AS room,MAX(inspection_date) AS date
FROM "TABLE_A" a
INNER JOIN lastDate ON a.room_id = lastDate.room and a.inspection_date < lastDate.date
GROUP BY room_id
), lastDateVacant AS (
SELECT room_id AS room FROM "TABLE_A"
WHERE (room_id,inspection_date) IN (
SELECT room, date FROM lastDate
) AND status = 'vacant'
), prevLastDateVacant AS (
SELECT room_id AS room FROM "TABLE_A"
WHERE (room_id,inspection_date) IN (
SELECT room, date FROM prevLastDate
) AND status = 'vacant'
)
SELECT a.* FROM "TABLE_A" a
INNER JOIN lastDateVacant
ON a.room_id = lastDateVacant.room
INNER JOIN prevLastDateVacant
ON a.room_id = prevLastDateVacant.room
LEFT OUTER JOIN "TABLE_B" AS b
ON a.room_id = b.room_id
WHERE b.room_id IS NULL
ORDER BY a.room_id ASC, a.inspection_date DESC
窗口功能
不确定TSQL的语法是否相同,但这是较短的变体:
按房间划分和按日期排序
检查排名为1和2的ID为“空置”状态的ID,按ID分组并多次出现
带房间AS(
选择房间(
选择room_id作为房间,状态,inspection_date作为日期,
RANK()OVER(由room_id ORDER BY inspection_date DESC划分)作为排名
来自“TABLE_A”
)
where(排名在(1,2)和status ='vacant')
按房间分组
有计数()&gt; 1
)
选择a。 FROM“TABLE_A”a
INNER JOIN会议室
在a.room_id = room.room
LEFT OUTER JOIN“TABLE_B”AS b
在a.room_id = b.room_id
在哪里b.room_id是空的
ORDER BY a.room_id ASC,a.inspection_date DESC
答案 1 :(得分:0)
您的条件几乎直接转换为查询。您可以使用窗口函数进行空置计数,将not exists
用于与table_b
的关系:
select a.*
from (select a.*,
sum(case when status = 'vacant' then 1 else 0 end) over (partition by room_id) as num_vacant
from table_a a
where not exists (select 1
from table_b b
where b.room_id = a.room_id
)
) a
where num_vacant >= 2;
编辑:
如果你想让最后两个空缺,你可以找到最后一个非空的记录,然后计算那些大于那个的记录:
select a.*
from (select a.*,
sum(case when a2.max_nonvacant > a.inspection_date then 0 else 1) over (partition by room_id) as num_vacant_last
from table_a a outer apply
(select max(inspection_date) as max_nonvacant
from table_a a2
where a2.room_id = a.room_id and a2.status <> 'vacant'
) a2
where not exists (select 1
from table_b b
where b.room_id = a.room_id
)
) a
where num_vacant_last >= 2;
答案 2 :(得分:0)
我做了这个测试: 提取考虑到与inspection_date(降序)相关的最后两个状态(相等状态)的所有room_id:
//example function which receives the sent data as well
function exampleLoggingCallback(sentData, receivedData, textStatus, jqXhr) {
console.log('Sent data: ' + sentData);
console.log('Received data: ' + receivedData);
}
//example call to your ajax function:
yourCustomAjaxFunction({foo: 'bar'}, exampleLoggingCallback);
答案 3 :(得分:0)
这对我有用,我一次又一次地检查过。
with Rooms as (
select
Room_Id, Status,
row_number() over (partition by Room_Id order by Inspection_Date desc) as rn
from TABLE_A
), Candidates as (
select Room_Id from Rooms group by Room_Id
having sum(case when rn in (1, 2) and Status = 'vacant' then 1 else null end) = 2
)
select * from TABLE_A
where Room_Id in (select Room_Id from Candidates except select Room_Id from TABLE_B)
order by Room_Id, Inspection_Date desc