मैं एक अद्यतन लिखना चाह रहा हूँ जो एक ऐसे झंडे को सही करेगा जो भटक ​​गया है।

मैं ACCOUNT_NUMBER द्वारा समूहीकृत न्यूनतम (TABLE_ID) के लिए PRIMARY_FLAG = 1 सेट करना चाहता हूं, जहां योग (PRIMARY_FLAG) <> 1 को ACCOUNT_NUMBER द्वारा समूहीकृत किया गया है।

यहाँ तालिका अब कैसी दिखती है:

TABLE_ID   ACCOUNT_NUMBER   PRIMARY_FLAG
--------   --------------   ------------
1          ABC123           0 
2          ABC123           1
3          ABC123           0
4          987XYZ           0
5          987XYZ           0
6          987XYZ           0
7          5A5B5C           1
8          5A5B5C           1
9          5A5B5C           0
10         5A5B5C           0

यहाँ मैं चाहता हूँ कि यह अद्यतन के बाद कैसा दिखे:

TABLE_ID   ACCOUNT_NUMBER   PRIMARY_FLAG
--------   --------------   ------------
1          ABC123           0 
2          ABC123           1
3          ABC123           0
4          987XYZ           1
5          987XYZ           0
6          987XYZ           0
7          5A5B5C           1
8          5A5B5C           0
9          5A5B5C           0
10         5A5B5C           0

परिदृश्य 1 - TABLE_ID 1, 2, 3 ACCOUNT_NUMBER = ABC123 के साथ पहले से ही सही है और मैं नहीं चाहता कि अपडेट इसे स्पर्श करे।

परिदृश्य 2 - ACCOUNT_NUMBER = 987XYZ, TABLE_ID में से किसी का भी PRIMARY_FLAG = 1 नहीं है, इसलिए अपडेट PRIMARY_FLAG = 1 को सेट करेगा जहां TABLE_ID = 4

परिदृश्य 3 - ACCOUNT_NUMBER = 5A5B5C में कई TABLE_ID = 1 हैं, इसलिए अपडेट TABLE_ID 7 छोड़ देगा लेकिन SET PRIMARY_FLAG = 0 जहां TABLE_ID = 8

मदद की सराहना है!

-1
TECHARM 15 नवम्बर 2019, 20:32
1
अपने प्रश्न को उस डेटाबेस के साथ टैग करें जिसका आप उपयोग कर रहे हैं।
 – 
Gordon Linoff
15 नवम्बर 2019, 20:35

2 जवाब

यहाँ एक सामान्य विधि है:

update t
    set primary_flag = (case when t.id = (select min(t2.id)
                                          from t t2
                                          where t2.account_number = t.account_number
                                         )
                             then 1 else 0
                        end)
    where t.account_number in (select t2.acount_number
                               from t t2
                               group by t2.acount_number
                               having sum(t2.primary_flag) <> 1
                              );

यह मानक SQL है और अधिकांश डेटाबेस में काम करेगा। हालाँकि, विशिष्ट डेटाबेस में समान कार्य करने के अधिक संक्षिप्त या कुशल तरीके हो सकते हैं।

0
Gordon Linoff 15 नवम्बर 2019, 20:37

तालिका में उस क्वेरी से जुड़ें जो अद्यतन किए जाने वाले प्रत्येक account_number के लिए न्यूनतम table_id लौटाती है:

update t 
set t.primary_flag = case when t.table_id = g.minid then 1 else 0 end
from tablename t inner join (
  select account_number, min(table_id) minid
  from tablename
  group by account_number
  having sum(primary_flag) <> 1
) g on g.account_number = t.account_number;

डेमो देखें।

या सीटीई के साथ:

with cte as (
  select *, 
    row_number() over (partition by account_number order by table_id) rn,
    sum(primary_flag) over (partition by account_number) total
  from tablename  
)
update cte 
set primary_flag = case when rn = 1 then 1 else 0 end
where total <> 1

डेमो देखें।
उन पंक्तियों के लिए अनावश्यक अद्यतनों से बचने के लिए जिन्हें अद्यतन करने की आवश्यकता नहीं है:

with cte as (
  select *, 
    row_number() over (partition by account_number order by table_id) rn,
    sum(primary_flag) over (partition by account_number) total
  from tablename  
)
update cte 
set primary_flag = abs(primary_flag - 1)
where (total <> 1) and ((rn = 1 and primary_flag = 0) or (rn > 1 and primary_flag = 1))

डेमो देखें।

परिणाम:

> TABLE_ID | ACCOUNT_NUMBER | PRIMARY_FLAG
> -------: | :------------- | -----------:
>        1 | ABC123         |            0
>        2 | ABC123         |            1
>        3 | ABC123         |            0
>        4 | 987XYZ         |            1
>        5 | 987XYZ         |            0
>        6 | 987XYZ         |            0
>        7 | 5A5B5C         |            1
>        8 | 5A5B5C         |            0
>        9 | 5A5B5C         |            0
>       10 | 5A5B5C         |            0
0
forpas 15 नवम्बर 2019, 21:19