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

क्या इस पुनरावर्ती समाधान को सीटीई या ओवर का उपयोग करके टी-एसक्यूएल क्वेरी में लिखा जा सकता है?

कुल चल रहा है। अद्यतन अस्थायी तालिका बनाम सीटीई

create table Test(
    OrderID int primary key,
    Qty int not null
);



declare @i int = 1;

while @i <= 5000 begin
    insert into Test(OrderID, Qty) values (@i * 2,rand() * 10); 
    set @i = @i + 1;
end;

पुनरावर्ती समाधान 9 सेकंड लगते हैं:

with T AS
(
    select ROW_NUMBER() over(order by OrderID) as rn, * from test
)
,R(Rn, OrderId, Qty, RunningTotal) as
(
    select Rn, OrderID, Qty, Qty
    from t 
    where rn = 1

    union all

    select t.Rn, t.OrderId, t.Qty, p.RunningTotal + t.Qty
    from t t
    join r p on t.rn = p.rn + 1

)
select R.OrderId, R.Qty, R.RunningTotal from r
option(maxrecursion 0);

अद्यतन तालिका 0 सेकंड लेता है:

create function TestRunningTotal()
returns @ReturnTable table(
    OrderId int, Qty int, RunningTotal int
)
as begin

    insert into @ReturnTable(OrderID, Qty, RunningTotal)
    select OrderID, Qty, 0 from Test
    order by OrderID;

    declare @RunningTotal int = 0;

    update @ReturnTable set 
           RunningTotal = @RunningTotal, 
           @RunningTotal = @RunningTotal + Qty;

    return;
end;

वे दो दृष्टिकोण कम से कम आपको अपनी क्वेरी बनाने के लिए एक ढांचा दे सकते हैं।

SQL सर्वर में BTW, MySQL के विपरीत, चर असाइनमेंट का क्रम मायने नहीं रखता। यह:

update @ReturnTable set 
    RunningTotal = @RunningTotal, 
    @RunningTotal = @RunningTotal + Qty;

और निम्नलिखित:

update @ReturnTable set 
    @RunningTotal = @RunningTotal + Qty,
    RunningTotal = @RunningTotal; 

वे दोनों एक ही तरह से निष्पादित करते हैं, यानी वैरिएबल असाइनमेंट पहले होते हैं, स्टेटमेंट में वेरिएबल असाइनमेंट की स्थिति की परवाह किए बिना। दोनों प्रश्नों का एक ही आउटपुट है:

OrderId     Qty         RunningTotal
----------- ----------- ------------
2           4           4
4           8           12
6           4           16
8           5           21
10          3           24
12          8           32
14          2           34
16          9           43
18          1           44
20          2           46
22          0           46
24          2           48
26          6           54

अपनी सटीक तालिका पर, बस खरीदें/बेचना का पता लगाएं, आप या तो इसे क्रमशः 1 और -1 से गुणा कर सकते हैं, या आप केवल फ़ील्ड पर हस्ताक्षर कर सकते हैं, उदा। :

update @ReturnTable set 
       @RunningTotal = @RunningTotal + 
                       CASE WHEN BuySell = 'Buy' THEN Qty ELSE -Qty END,
       RunningTotal = @RunningTotal;            

यदि आप SQL Server 2012 में अपग्रेड करते हैं, तो यहां कुल रनिंग का सीधा कार्यान्वयन है:

select OrderID, Qty, sum(Qty) over(order by OrderID) as RunningTotal
from Test

आपकी सटीक समस्या पर:

select OrderID, Qty, 

   sum(CASE WHEN BuySell = 'Buy' THEN Qty ELSE -Qty END) 
   over(order by OrderID) as RunningTotal

from Test;

अपडेट करें

अगर आप से असहज महसूस करते हैं। विचित्र अपडेट , आप यह जांचने के लिए एक गार्ड क्लॉज लगा सकते हैं कि क्या अद्यतन की जाने वाली पंक्तियों का क्रम मूल क्रम से मेल खाता है (पहचान द्वारा सहायता प्राप्त (1,1)):

create function TestRunningTotalGuarded()
returns @ReturnTable table(
    OrderId int, Qty int, 
    RunningTotal int not null, 
    RN int identity(1,1) not null
)
as begin

    insert into @ReturnTable(OrderID, Qty, RunningTotal)
    select OrderID, Qty, 0 from Test
    order by OrderID;

    declare @RunningTotal int = 0;

    declare @RN_check INT = 0;

    update @ReturnTable set 
            @RN_check = @RN_check + 1,
            @RunningTotal = 
                (case when RN = @RN_check then @RunningTotal + Qty else 1/0 end),
            RunningTotal = @RunningTotal;

    return;

end;

यदि UPDATE वास्तव में अप्रत्याशित क्रम में पंक्तियों को अपडेट करता है (या किसी भी तरह से यह होगा), तो @RN_Check अब RN (पहचान आदेश) के बराबर नहीं होगा, कोड एक डिवाइड-बाय-जीरो एरर बढ़ाएगा। फिर। गार्ड क्लॉज का उपयोग करते हुए, अप्रत्याशित अपडेट ऑर्डर तेजी से विफल हो जाएगा।; अगर ऐसा होता है, तो यह समय एक <स्ट्राइक>बग दर्ज करने का होगा Microsoft से अनुरोध करें कि इस विचित्र अद्यतन को इतना विचित्र न बनाया जाए :-)

स्वाभाविक रूप से अनिवार्य संचालन (चर असाइनमेंट) पर गार्ड क्लॉज हेज वास्तव में अनुक्रमिक है।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL सर्वर लॉग शिपिंग और डिजास्टर रिकवरी इंस्टाल और कॉन्फ़िगरेशन -2

  2. SQL सर्वर चुपचाप संग्रहीत कार्यविधियों में varchar की काट-छाँट करता है

  3. SQL सर्वर 2016 स्थापित करें

  4. संग्रहित प्रक्रिया में लेजर रिपोर्ट तर्क

  5. दिनांक और/या समय को वर्ण स्ट्रिंग से कनवर्ट करते समय रूपांतरण विफल रहा