Ето как изглеждат възможните припокривания, където „A“ е „референтният“ интервал. Имайте предвид, че заявката по-долу (далеч, много по-долу) не дава същия резултат като нито един от отговорите, които все още са публикувани.
<предварителен код>-- A |------|-- B |-|-- C |---|-- D |---|-- E |---|-- F |---|-- G |---|-- H |---|-- I |---|"B" изобщо не се припокрива с "A". "C" се допира до него. {"D", "E", "F", "G"} го припокрива. "H" се допира до него. "I" изобщо не го припокрива.
създайте таблица calls_nov ( sid varchar(5) първичен ключ, начален времеви печат не е нулев, краен времеви печат не е нулев); вмъкване в стойности на calls_nov('A', '2012-01-04 08:00:00', '2012-01-04 08:00:10'),('B', '2012-01-04 07:50 :00', '2012-01-04 07:50:03'),('C', '2012-01-04 07:59:57', '2012-01-04 08:00:00'), ('D', '2012-01-04 07:59:57', '2012-01-04 08:00:03'),('E', '2012-01-04 08:00:01', '2012-01-04 08:00:04'),('F', '2012-01-04 08:00:07', '2012-01-04 08:00:10'),('G' , '2012-01-04 08:00:07', '2012-01-04 08:00:13'),('H', '2012-01-04 08:00:10', '2012-01 -04 08:00:13'),('I', '2012-01-04 08:00:15', '2012-01-04 08:00:18');
Можете да видите всички припокриващи се интервали по този начин. (Току-що използвах to_char(), за да улесня прегледа на всички данни. Можете да го пропуснете в производството.)
изберете t1.sid, to_char(t1.starttime, 'HH12:MI:SS'), to_char(t1.endtime, 'HH12:MI:SS'), t2.sid, to_char(t2.starttime , 'HH12:MI:SS'), to_char(t2.endtime, 'HH12:MI:SS')от calls_nov t1inner join calls_nov t2 на (t2.starttime, t2.endtime) се припокрива (t1.starttime, t1.endtime) поръчайте от t1.sid, t2.sid;A 08:00:00 08:00:10 A 08:00:00 08:00:10A 08:00:00 08:00:10 D 07:59:57 08:00:03A 08:00:00 08:00:10 E 08:00:01 08:00:04A 08:00:00 08:00:10 F 08:00:07 08:00:10A 08:00:00 08:00:10 G 08:00:07 08:00:13B 07:50:00 07:50:03 B 07:50:00 07:50:03C 07:59:57 8:00:00 C 07:59:57 08:00:00C 07:59:57 08:00:00 D 07:59:57 08:00:03D 07:59:57 08:00:03 A 08:00:00 08:00:10D 07:59:57 08:00:03 C 07:59:57 08:00:00D 07:59:57 08:00:03 D 07:59:57 08:00:03D 07:59:57 08:00 :03 E 08:00:01 08:00:04E 08:00:01 08:00:04 A 08:00:00 08:00 :10E 08:00:01 08:00:04 D 07:59:57 08:00:03E 08:00:01 08:00:04 E 08:00:01 08:00:04F 08:00:07 08 :00:10 A 08:00:00 08:00:10F 08:00:07 08:00:10 F 08:00:07 08:00:10F 08:00:07 08:00:10 G 08:00 :07 08:00:13G 08:00:07 08:00:13 A 08:00:00 08:00:10G 08:00:07 08:00:13 F 08:00:07 08:00:10G 08 :00:07 08:00:13 G 08:00:07 08:00:13G 08:00:07 08:00:13 H 08:00:10 08:00:13H 08:00:10 08:00:13 G 08:00:07 08:00:13H 08:00:10 08:00:13 H 08:00:10 08:00:13I 08:00:15 08:00:18 I 08:00:15 08 :00:18
Можете да видите от тази таблица, че "А" трябва да брои 5, включително себе си. "B" трябва да брои 1; той се припокрива сам, но никакви други интервали не го припокриват. Изглежда, че това е правилното нещо.
Броенето е лесно, но върви като разкъсана костенурка. Това е така, защото оценяването на припокриване изисква много работа.
select t1.sid, count(t2.sid) as num_concurrentfrom calls_nov t1inner join calls_nov t2 on (t2.starttime, t2.endtime) припокрива (t1.starttime, t1.endtime) група по t1.sidorder от num_concurrent desc;A 5D 4G 4E 3F 3H 2C 2I 1B 1
За да постигнете по-добра производителност, можете да използвате „таблицата“ по-горе в общ табличен израз и да преброите въз основа на това .
с интервал_таблица като (изберете t1.sid като sid_1, t1.starttime, t1.endtime, t2.sid като sid_2, t2.starttime, t2.endtimefrom calls_nov t1inner join calls_nov t2 on (t2.starttime, t2.starttime, t2.endtime) .endtime) припокрива (t1.starttime, t1.endtime) подреждане по t1.sid, t2.sid) изберете sid_1, count(sid_2) като num_concurrentfrom interval_tablegroup по sid_1order по num_concurrent desc;