PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

SQL में समवर्ती घटनाओं की संख्या की गणना करें

यहां संभावित ओवरलैप कैसा दिखता है, जहां 'ए' "संदर्भ" अंतराल है। ध्यान दें कि नीचे दी गई क्वेरी (दूर, बहुत नीचे) अभी तक पोस्ट किए गए किसी भी उत्तर के समान परिणाम नहीं देती है।

-- A            |------|
-- B |-|
-- C        |---|
-- D          |---|
-- E             |---|
-- F               |---|
-- G                 |---|
-- H                   |---|
-- I                       |---|

"बी" "ए" को बिल्कुल ओवरलैप नहीं करता है। "सी" इसे बंद कर देता है। {"D", "E", "F", "G"} इसे ओवरलैप करता है। "एच" इसे बंद कर देता है। "I" इसे बिल्कुल भी ओवरलैप नहीं करता है।

create table calls_nov (
  sid varchar(5) primary key,
  starttime timestamp not null,
  endtime timestamp not null
);  

insert into calls_nov values
('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() का उपयोग किया है। आप इसे उत्पादन में छोड़ सकते हैं।)

select 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')
from calls_nov t1
inner join calls_nov t2 on (t2.starttime, t2.endtime) 
                  overlaps (t1.starttime, t1.endtime) 
order by t1.sid, t2.sid;

A   08:00:00   08:00:10   A   08:00:00   08:00:10
A   08:00:00   08:00:10   D   07:59:57   08:00:03
A   08:00:00   08:00:10   E   08:00:01   08:00:04
A   08:00:00   08:00:10   F   08:00:07   08:00:10
A   08:00:00   08:00:10   G   08:00:07   08:00:13
B   07:50:00   07:50:03   B   07:50:00   07:50:03
C   07:59:57   08:00:00   C   07:59:57   08:00:00
C   07:59:57   08:00:00   D   07:59:57   08:00:03
D   07:59:57   08:00:03   A   08:00:00   08:00:10
D   07:59:57   08:00:03   C   07:59:57   08:00:00
D   07:59:57   08:00:03   D   07:59:57   08:00:03
D   07:59:57   08:00:03   E   08:00:01   08:00:04
E   08:00:01   08:00:04   A   08:00:00   08:00:10
E   08:00:01   08:00:04   D   07:59:57   08:00:03
E   08:00:01   08:00:04   E   08:00:01   08:00:04
F   08:00:07   08:00:10   A   08:00:00   08:00:10
F   08:00:07   08:00:10   F   08:00:07   08:00:10
F   08:00:07   08:00:10   G   08:00:07   08:00:13
G   08:00:07   08:00:13   A   08:00:00   08:00:10
G   08:00:07   08:00:13   F   08:00:07   08:00:10
G   08:00:07   08:00:13   G   08:00:07   08:00:13
G   08:00:07   08:00:13   H   08:00:10   08:00:13
H   08:00:10   08:00:13   G   08:00:07   08:00:13
H   08:00:10   08:00:13   H   08:00:10   08:00:13
I   08:00:15   08:00:18   I   08:00:15   08:00:18

आप इस तालिका से देख सकते हैं कि "ए" को स्वयं सहित 5 की गणना करनी चाहिए। "बी" को 1 गिनना चाहिए; यह खुद को ओवरलैप करता है, लेकिन कोई अन्य अंतराल इसे ओवरलैप नहीं करता है। ऐसा करना सही लगता है।

गिनती सीधी है, लेकिन टूटे हुए कछुए की तरह चलती है। ऐसा इसलिए है क्योंकि ओवरलैप का मूल्यांकन करने में बहुत काम लगता है।

select t1.sid, count(t2.sid) as num_concurrent
from calls_nov t1
inner join calls_nov t2 on (t2.starttime, t2.endtime) 
                  overlaps (t1.starttime, t1.endtime) 
group by t1.sid
order by num_concurrent desc;

A   5
D   4
G   4
E   3
F   3
H   2
C   2
I   1
B   1

बेहतर प्रदर्शन प्राप्त करने के लिए, आप उपरोक्त "तालिका" का उपयोग सामान्य तालिका अभिव्यक्ति में कर सकते हैं, और उस के आधार पर गणना कर सकते हैं ।

with interval_table as (
select t1.sid as sid_1, t1.starttime, t1.endtime,
       t2.sid as sid_2, t2.starttime, t2.endtime
from calls_nov t1
inner join calls_nov t2 on (t2.starttime, t2.endtime) 
                  overlaps (t1.starttime, t1.endtime) 
order by t1.sid, t2.sid
) 
select sid_1, count(sid_2) as num_concurrent
from interval_table
group by sid_1
order by num_concurrent desc;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL ने उपयोगकर्ताओं और समूहों को भूमिकाओं में विलय क्यों किया?

  2. हालिया रिलीज के साथ नई और विकसित पोस्टग्रेएसक्यूएल एंटरप्राइज़ सुविधाएं

  3. मावेन-असेंबली-प्लगइन के साथ आवश्यक ड्राइवरों को शामिल करते समय कोई उपयुक्त ड्राइवर नहीं मिला

  4. PostgreSQL में किसी संख्या को प्रतिशत के रूप में प्रारूपित करने के 3 तरीके

  5. कैसे pg_sleep_for () PostgreSQL में काम करता है