इसे आज़माएं:http://www.sqlfiddle.com/#!3/c3365/ 20
with s as
(
select *, row_number() over(partition by membercode order by startdate) rn
from tbl
)
,gaps as
(
select a.membercode, a.startdate, a.enddate, b.startdate as nextstartdate
,datediff(d, a.enddate, b.startdate) as gap
from s a
join s b on b.membercode = a.membercode and b.rn = a.rn + 1
)
select membercode
from gaps
group by membercode
having sum(case when gap <= 1 then 1 end) = count(*);
क्वेरी की प्रगति यहां देखें:http://www.sqlfiddle.com/#!3/ c3365/20
यह कैसे काम करता है, वर्तमान समाप्ति तिथि की तुलना इसकी अगली प्रारंभ तिथि से करें और तिथि अंतराल की जांच करें:
with s as
(
select *, row_number() over(partition by membercode order by startdate) rn
from tbl
)
select a.membercode, a.startdate, a.enddate, b.startdate as nextstartdate
,datediff(d, a.enddate, b.startdate) as gap
from s a
join s b on b.membercode = a.membercode and b.rn = a.rn + 1;
आउटपुट:
| MEMBERCODE | STARTDATE | ENDDATE | NEXTSTARTDATE | GAP |
--------------------------------------------------------------
| 1 | 2010-01-15 | 2010-01-20 | 2010-01-19 | -1 |
| 1 | 2010-01-19 | 2010-01-22 | 2010-01-20 | -2 |
| 1 | 2010-01-20 | 2010-01-25 | 2010-01-26 | 1 |
| 2 | 2010-01-20 | 2010-01-25 | 2010-01-30 | 5 |
| 2 | 2010-01-30 | 2010-02-05 | 2010-02-04 | -1 |
फिर जांचें कि क्या किसी सदस्य के दावों की संख्या समान है और उसके कुल दावों में कोई अंतर नहीं है:
with s as
(
select *, row_number() over(partition by membercode order by startdate) rn
from tbl
)
,gaps as
(
select a.membercode, a.startdate, a.enddate, b.startdate as nextstartdate
,datediff(d, a.enddate, b.startdate) as gap
from s a
join s b on b.membercode = a.membercode and b.rn = a.rn + 1
)
select membercode, count(*) as count, sum(case when gap <= 1 then 1 end) as gapless_count
from gaps
group by membercode;
आउटपुट:
| MEMBERCODE | COUNT | GAPLESS_COUNT |
--------------------------------------
| 1 | 3 | 3 |
| 2 | 2 | 1 |
अंत में, उन सदस्यों को फ़िल्टर करें जिनके दावों में कोई अंतर नहीं है:
with s as
(
select *, row_number() over(partition by membercode order by startdate) rn
from tbl
)
,gaps as
(
select a.membercode, a.startdate, a.enddate, b.startdate as nextstartdate
,datediff(d, a.enddate, b.startdate) as gap
from s a
join s b on b.membercode = a.membercode and b.rn = a.rn + 1
)
select membercode
from gaps
group by membercode
having sum(case when gap <= 1 then 1 end) = count(*);
आउटपुट:
| MEMBERCODE |
--------------
| 1 |
ध्यान दें कि आपको COUNT(*) > 1
. करने की आवश्यकता नहीं है 2 या अधिक दावों वाले सदस्यों का पता लगाने के लिए। LEFT JOIN
का उपयोग करने के बजाय , हम JOIN
. का उपयोग करते हैं , यह स्वचालित रूप से उन सदस्यों को खारिज कर देगा जिनके पास अभी तक दूसरा दावा नहीं है। यदि आप LEFT JOIN
use का उपयोग करने का विकल्प चुनते हैं तो यहां संस्करण (लंबा) है इसके बजाय (ऊपर जैसा आउटपुट):
with s as
(
select *, row_number() over(partition by membercode order by startdate) rn
from tbl
)
,gaps as
(
select a.membercode, a.startdate, a.enddate, b.startdate as nextstartdate
,datediff(d, a.enddate, b.startdate) as gap
from s a
left join s b on b.membercode = a.membercode and b.rn = a.rn + 1
)
select membercode
from gaps
group by membercode
having sum(case when gap <= 1 then 1 end) = count(gap)
and count(*) > 1; -- members who have two ore more claims only
फ़िल्टर करने से पहले उपरोक्त क्वेरी का डेटा कैसे देखें:
with s as
(
select *, row_number() over(partition by membercode order by startdate) rn
from tbl
)
,gaps as
(
select a.membercode, a.startdate, a.enddate, b.startdate as nextstartdate
,datediff(d, a.enddate, b.startdate) as gap
from s a
left join s b on b.membercode = a.membercode and b.rn = a.rn + 1
)
select * from gaps;
आउटपुट:
| MEMBERCODE | STARTDATE | ENDDATE | NEXTSTARTDATE | GAP |
-----------------------------------------------------------------
| 1 | 2010-01-15 | 2010-01-20 | 2010-01-19 | -1 |
| 1 | 2010-01-19 | 2010-01-22 | 2010-01-20 | -2 |
| 1 | 2010-01-20 | 2010-01-25 | 2010-01-26 | 1 |
| 1 | 2010-01-26 | 2010-01-30 | (null) | (null) |
| 2 | 2010-01-20 | 2010-01-25 | 2010-01-30 | 5 |
| 2 | 2010-01-30 | 2010-02-05 | 2010-02-04 | -1 |
| 2 | 2010-02-04 | 2010-02-15 | (null) | (null) |
| 3 | 2010-02-15 | 2010-03-02 | (null) | (null) |
संपादित करें आवश्यकता स्पष्टीकरण पर:
अपने स्पष्टीकरण पर, आप उन सदस्यों को शामिल करना चाहते हैं जिनके पास अभी तक दूसरा दावा नहीं है, इसके बजाय इसे करें:http://sqlfiddle.com/#!3/c3365/22
with s as
(
select *, row_number() over(partition by membercode order by startdate) rn
from tbl
)
,gaps as
(
select a.membercode, a.startdate, a.enddate, b.startdate as nextstartdate
,datediff(d, a.enddate, b.startdate) as gap
from s a
left join s b on b.membercode = a.membercode and b.rn = a.rn + 1
)
select membercode
from gaps
group by membercode
having sum(case when gap <= 1 then 1 end) = count(gap)
-- members who have yet to have a second claim are valid too
or count(nextstartdate) = 0;
आउटपुट:
| MEMBERCODE |
--------------
| 1 |
| 3 |
तकनीक सदस्य की nextstartdate
. को गिनने की है , यदि उनके पास कोई अगली प्रारंभ तिथि दिनांक नहीं है (अर्थात count(nextstartdate) = 0
) तो वे केवल एकल दावे हैं और मान्य भी हैं, तो बस इसे संलग्न करें OR
शर्त:
or count(nextstartdate) = 0;
वास्तव में, नीचे दी गई शर्त भी पर्याप्त होगी, हालांकि मैं क्वेरी को और अधिक स्व-दस्तावेज बनाना चाहता था, इसलिए मैं सदस्य की अगली शुरुआत की गणना करने की सलाह देता हूं। यहां उन सदस्यों की गिनती के लिए एक वैकल्पिक शर्त दी गई है जिनके पास अभी तक दूसरा दावा नहीं है:
or count(*) = 1;
बीटीडब्ल्यू, हमें इससे तुलना भी बदलनी होगी:
sum(case when gap <= 1 then 1 end) = count(*)
इसके लिए (जैसा कि हम LEFT JOIN
. का उपयोग कर रहे हैं अभी):
sum(case when gap <= 1 then 1 end) = count(gap)