下面是我的剧院表:
create table theater
(
srno integer,
seatno integer,
available boolean
);
insert into theater
values
(1, 100,true),
(2, 200,true),
(3, 300,true),
(4, 400,false),
(5, 500,true),
(6, 600,true),
(7, 700,true),
(8, 800,true);
我想要一个sql,它应该输入' n'并给我第一个' n'连续可用的席位,如
注意:我正在尝试为postgres 9.3构建查询
答案 0 :(得分:3)
在 SQL-Server 中,您可以执行以下操作:
DECLARE @num INT = 4
;WITH cte AS
(
SELECT *,COUNT(1) OVER(PARTITION BY cnt) pt FROM
(
SELECT tt.*
,(SELECT COUNT(srno) FROM theater t WHERE available <> 'true' and srno < tt.srno) AS cnt
FROM theater tt
WHERE available = 'true'
) t1
)
SELECT TOP (SELECT @num) srno, seatno, available
FROM cte
WHERE pt >= @num
<强>输出强>
srno seatno available
5 500 true
6 600 true
7 700 true
8 800 true
答案 1 :(得分:2)
这将找到可用的座位。为sqlserver 2008 +编写:
DECLARE @num INT = 4
;WITH CTE as
(
SELECT
srno-row_number() over (partition by available order by srno) grp,
srno, seatno, available
FROM theater
), CTE2 as
(
SELECT grp, count(*) over (partition by grp) cnt,
srno, seatno, available
FROM CTE
WHERE available = 'true'
)
SELECT top(@num)
srno, seatno, available
FROM CTE2
WHERE cnt >= @num
ORDER BY srno
结果:
srno seatno available
5 500 1
6 600 1
7 700 1
8 800 1
答案 2 :(得分:0)
-- naive solution without window using functions
-- [the funny +-100 constants are caused by
-- "consecutive" seats being 100 apart]
-- -------------------------------------------
WITH bot AS ( -- start of an island --
SELECT seatno FROM theater t
WHERE t.available
AND NOT EXISTS (select * from theater x
where x.available AND x.seatno = t.seatno -100)
)
, top AS ( -- end of an island --
SELECT seatno FROM theater t
WHERE t.available
AND NOT EXISTS (select * from theater x
where x.available AND x.seatno = t.seatno +100)
)
, mid AS ( -- [start,end] without intervening gaps --
SELECT l.seatno AS bot, h.seatno AS top
FROM bot l
JOIN top h ON h.seatno >= l.seatno
AND NOT EXISTS (
SELECT * FROM theater x
WHERE NOT x.available
AND x.seatno >= l.seatno AND x.seatno <= h.seatno)
)
-- all the consecutive ranges
-- [ the end query should select from this
-- , using "cnt >= xxx" ]
SELECT bot, top
, 1+(top-bot)/100 AS cnt
FROM mid;
结果:
bot | top | cnt
-----+-----+-----
100 | 300 | 3
500 | 800 | 4
(2 rows)
答案 3 :(得分:-2)
谢谢你们,但我已经完成了如下所示,
select srno, seatno from ( select *, count(0) over (order by grp) grp1 from ( select t1.*, sum(group_flag) over (order by srno) as grp from ( select *, case when lag(available) over (order by srno) = available then null else 1 end as group_flag from theater ) t1 ) tx ) tr where tr.available=true and tr.grp1 >= 2 limit 2