কিভাবে যোগফল যোগফল পাবেন


185
declare  @t table
    (
        id int,
        SomeNumt int
    )

insert into @t
select 1,10
union
select 2,12
union
select 3,3
union
select 4,15
union
select 5,23


select * from @t

উপরের সিলেক্ট আমাকে নীচে ফিরিয়ে দেয়।

id  SomeNumt
1   10
2   12
3   3
4   15
5   23

আমি কীভাবে নিম্নলিখিত পেতে পারি:

id  srome   CumSrome
1   10  10
2   12  22
3   3   25
4   15  40
5   23  63

5
টি-এসকিউএলে মোট রান পাওয়া শক্ত নয়, অনেকগুলি সঠিক উত্তর রয়েছে, যার মধ্যে বেশিরভাগই বেশ সহজ। মোটামুটি কার্যকর নয় (বা এই সময়ে এমনকি সম্ভব) কী পরিমাণ দক্ষ তা চালানোর জন্য টি-এসকিউএলে একটি সত্য কোয়েরি লিখতে হয়। তারা সকলেই হে (এন ^ 2), যদিও তারা সহজেই ও (এন) হতে পারে, টি-এসকিউএল এ ক্ষেত্রে অনুকূল নয় optim আপনি ও (এন) কার্সার এবং / অথবা লুপগুলি ব্যবহার করে পেতে পারেন তবে তারপরে আপনি কার্সার ব্যবহার করছেন। ( ব্লিচ! )
আরবেরি ইয়ং

উত্তর:


225
select t1.id, t1.SomeNumt, SUM(t2.SomeNumt) as sum
from @t t1
inner join @t t2 on t1.id >= t2.id
group by t1.id, t1.SomeNumt
order by t1.id

এসকিউএল ফিডল উদাহরণ

আউটপুট

| ID | SOMENUMT | SUM |
-----------------------
|  1 |       10 |  10 |
|  2 |       12 |  22 |
|  3 |        3 |  25 |
|  4 |       15 |  40 |
|  5 |       23 |  63 |

সম্পাদনা করুন: এটি একটি সাধারণ সমাধান যা বেশিরভাগ ডিবি প্ল্যাটফর্ম জুড়ে কাজ করবে। আপনার নির্দিষ্ট প্ল্যাটফর্মের (যেমন, গ্যারেথের) জন্য আরও ভাল সমাধান যখন পাওয়া যায়, তখন এটি ব্যবহার করুন!


12
@ ফ্র্যাঙ্কলিন শুধুমাত্র ছোট টেবিলের জন্য ব্যয় সাশ্রয়ী। সারিগুলির সংখ্যার বর্গক্ষেত্রের তুলনামুলক ব্যয় বৃদ্ধি পায়। এসকিউএল সার্ভার 2012 এটি আরও বেশি দক্ষতার সাথে করার অনুমতি দেয়।
মার্টিন স্মিথ

3
এফডাব্লুআইডাব্লু, ডিবিএর মাধ্যমে এই কাজটি করার সময় আমার নাকসগুলি স্ম্যাক করা হয়েছিল। আমি মনে করি কারণ এটি সত্যই ব্যয়বহুল হয়ে যায়, সত্যই দ্রুত। বলা হচ্ছে, এটি একটি দুর্দান্ত সাক্ষাত্কারের প্রশ্ন, কারণ বেশিরভাগ ডেটা বিশ্লেষক / বিজ্ঞানীদের এই সমস্যাটি একবার বা দু'বার সমাধান করা উচিত ছিল :)
বেনডান্ডি

@ বেনডুন্ডি রাজি - আমি সাধারণ এসকিউএল সমাধান সরবরাহ করি যা বেশিরভাগ ডিবি প্ল্যাটফর্মে কাজ করবে on সর্বদা হিসাবে, যখন আরও ভাল পদ্ধতির উপলব্ধ থাকে, যেমন, গ্যারেথ, এটি ব্যবহার করুন!
রেডফিল্টার

198

এসকিউএল সার্ভারের সর্বশেষতম সংস্করণ (২০১২) নিম্নলিখিতটির অনুমতি দেয়।

SELECT 
    RowID, 
    Col1,
    SUM(Col1) OVER(ORDER BY RowId ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Col2
FROM tablehh
ORDER BY RowId

অথবা

SELECT 
    GroupID, 
    RowID, 
    Col1,
    SUM(Col1) OVER(PARTITION BY GroupID ORDER BY RowId ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Col2
FROM tablehh
ORDER BY RowId

এটি আরও দ্রুত। পার্টিশনযুক্ত সংস্করণটি আমার জন্য 5 মিলিয়ন সারিতে 34 সেকেন্ডে সম্পূর্ণ হয়।

পেসোর ধন্যবাদ, যিনি অন্য উত্তরে উল্লেখ করা এসকিউএল টিম থ্রেডে মন্তব্য করেছিলেন।


22
বংশবৃদ্ধির জন্য, আপনি এর ROWS UNBOUNDED PRECEDINGপরিবর্তে ব্যবহার করতে পারেন ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
ড্যান

1
দ্রষ্টব্য: আপনি যে কলামটি সংযোজিতভাবে যোগ করতে চান তা যদি ইতিমধ্যে একটি যোগ বা গণনা হয় তবে আপনি হয় পুরো জিনিসটিকে অভ্যন্তরীণ কোয়েরি হিসাবে মোড়ানো করতে পারেন বা আপনি আসলে করতে পারেন SUM(COUNT(*)) OVER (ORDER BY RowId ROWS UNBOUNDED PRECEDING) AS CumulativeSum। এটি কাজ করে কিনা তা আমার কাছে তাত্ক্ষণিকভাবে স্পষ্ট ছিল না তবে এটি হয়েছিল :-)
সাইমন_উইভার

8.4 হিসাবে পোস্টগ্রি এখানে পাওয়া যাবে: postgresql.org/docs/8.4/sql-select.html
ADJenks

27

এসকিউএল সার্ভার ২০১২ এর পরে এটি সহজ হতে পারে:

SELECT id, SomeNumt, sum(SomeNumt) OVER (ORDER BY id) as CumSrome FROM @t

কারণ উইন্ডো ফ্রেমের জন্য ডিফল্টরূপে ORDER BYজন্য ধারা ( https://msdn.microsoft.com/en-us/library/ms189461.aspx এ "সাধারণ মন্তব্য" )SUMRANGE UNBOUNDED PRECEDING AND CURRENT ROW


13

একটি মজাদার জন্য একটি সিটিই সংস্করণ:

;
WITH  abcd
        AS ( SELECT id
                   ,SomeNumt
                   ,SomeNumt AS MySum
             FROM   @t
             WHERE  id = 1
             UNION ALL
             SELECT t.id
                   ,t.SomeNumt
                   ,t.SomeNumt + a.MySum AS MySum
             FROM   @t AS t
                    JOIN abcd AS a ON a.id = t.id - 1
           )
  SELECT  *  FROM    abcd
OPTION  ( MAXRECURSION 1000 ) -- limit recursion here, or 0 for no limit.

রিটার্নস:

id          SomeNumt    MySum
----------- ----------- -----------
1           10          10
2           12          22
3           3           25
4           15          40
5           23          63

12

প্রথমে ডামি ডেটা -> সহ একটি টেবিল তৈরি করতে দেয়

Create Table CUMULATIVESUM (id tinyint , SomeValue tinyint)

**Now let put some data in the table**

Insert Into CUMULATIVESUM

Select 1, 10 union 
Select 2, 2  union
Select 3, 6  union
Select 4, 10 

এখানে আমি একই টেবিলে যোগ দিচ্ছি (নিজের সাথে যোগদান)

Select c1.ID, c1.SomeValue, c2.SomeValue
From CumulativeSum c1,  CumulativeSum c2
Where c1.id >= c2.ID
Order By c1.id Asc

ফলাফল :

ID  SomeValue   SomeValue
1   10          10
2   2           10
2   2            2
3   6           10
3   6            2
3   6            6
4   10          10
4   10           2
4   10           6
4   10          10

এখানে আমরা এখন t2 এর সমমূল্য যোগফল এবং উত্তরগুলি পেয়ে যাব

Select c1.ID, c1.SomeValue, Sum(c2.SomeValue) CumulativeSumValue
From CumulativeSum c1,  CumulativeSum c2
Where c1.id >= c2.ID
Group By c1.ID, c1.SomeValue
Order By c1.id Asc

এসকিউএল সার্ভার ২০১২ এবং তারপরের জন্য (আরও ভাল পারফরম্যান্স)

Select c1.ID, c1.SomeValue, 
SUM (SomeValue) OVER (ORDER BY c1.ID )
From CumulativeSum c1
Order By c1.id Asc

কাঙ্ক্ষিত ফলাফল

ID  SomeValue   CumlativeSumValue
1   10          10
2   2           12
3   6           18
4   10          28

Drop Table CumulativeSum

Dummytable সাফ করুন


দয়া করে আপনার উত্তরটি সম্পাদনা করুন এবং
কোডটিকে

যদি আমার "আইডি" মানগুলি পুনরাবৃত্তি হয়? (তারা আমার টেবিলের স্বতঃস্ফূর্তভাবে প্রাথমিক কী নয়) আমি এই ক্যোয়ারিকে সে ক্ষেত্রে মানিয়ে নিতে সক্ষম হইনি?
pablete

এএআইএআইএইচিকে আপনার ক্রমসংখ্যার জন্য অনন্য আইডি দরকার এবং আপনি সারি_সংখ্যার সাহায্যে এটি পেতে পারেন। নীচের কোডটি চেক করুন:; নিউটিবিএলবিটহানিকিআইডির সাথে (সারি_সংখ্যা (ওভারের অর্ডার, কিছু মূল্য) অর্ডার নির্বাচন করুন) ইউনিকআইডি, * সংক্ষিপ্তসার ব্যতীত পি কে থেকে
নীরজ প্রসাদ শর্মা

ধন্যবাদ @ নীরাজপ্রসাদ শর্মা, আমি আসলে এটি ব্যবহার rank()করার জন্য ক্লজ দ্বারা অন্য একটি আদেশ ব্যবহার করেছি।
pablete

5

দেরিতে উত্তর তবে আরও একটি সম্ভাবনা দেখাচ্ছে ...

CROSS APPLYযৌক্তিক সমষ্টি প্রজন্মকে যুক্তি দিয়ে আরও অনুকূলিত করা যেতে পারে ।

প্রকৃত ক্যোয়ারী পরিকল্পনার বিশ্লেষণ করার সময় INNER JOIN& এর থেকেও ভাল কাজ করে OVER Clause...

/* Create table & populate data */
IF OBJECT_ID('tempdb..#TMP') IS NOT NULL
DROP TABLE #TMP 

SELECT * INTO #TMP 
FROM (
SELECT 1 AS id
UNION 
SELECT 2 AS id
UNION 
SELECT 3 AS id
UNION 
SELECT 4 AS id
UNION 
SELECT 5 AS id
) Tab


/* Using CROSS APPLY 
Query cost relative to the batch 17%
*/    
SELECT   T1.id, 
         T2.CumSum 
FROM     #TMP T1 
         CROSS APPLY ( 
         SELECT   SUM(T2.id) AS CumSum 
         FROM     #TMP T2 
         WHERE    T1.id >= T2.id
         ) T2

/* Using INNER JOIN 
Query cost relative to the batch 46%
*/
SELECT   T1.id, 
         SUM(T2.id) CumSum
FROM     #TMP T1
         INNER JOIN #TMP T2
                 ON T1.id > = T2.id
GROUP BY T1.id

/* Using OVER clause
Query cost relative to the batch 37%
*/
SELECT   T1.id, 
         SUM(T1.id) OVER( PARTITION BY id)
FROM     #TMP T1

Output:-
  id       CumSum
-------   ------- 
   1         1
   2         3
   3         6
   4         10
   5         15

1
আমি রাজি হই না। "ব্যাচের তুলনায় ক্যোয়ারী ব্যয়" কোয়েরিগুলির পারফরম্যান্সের তুলনা করার জন্য একটি অর্থহীন জিনিস। ক্যোয়ারী পরিকল্পনাকারী ক্যোয়ারী পরিকল্পনাকারীর দ্বারা ক্যোয়ারী ব্যয়গুলি হ'ল প্রাক্কলন হিসাবে বিভিন্ন পরিকল্পনা দ্রুত ওজন করতে এবং সর্বনিম্ন ব্যয়বহুল বেছে নিতে, তবে সেই ব্যয়গুলি একই ক্যোয়ারির জন্য পরিকল্পনাগুলির তুলনা করার জন্য এবং প্রাসঙ্গিক বা কোয়েরির সাথে তুলনীয় নয়, মোটেই নয়। তিনটি পদ্ধতির মধ্যে কোনও উল্লেখযোগ্য পার্থক্য দেখতে এই নমুনা ডেটাসেটটিও খুব ছোট। 1 মি সারির সাহায্যে এটি আবার চেষ্টা করুন, প্রকৃত বাস্তবায়ন পরিকল্পনাটি দেখুন, set io statistics onসিপিইউ এবং আসল সময়গুলির সাথে এটি ব্যবহার করে দেখুন।
দাভোস

4

Select *, (Select SUM(SOMENUMT) From @t S Where S.id <= M.id) From @t M


এটি ফলাফলটি অর্জনের খুব স্মার্ট উপায় এবং আপনি যোগফলটিতে একাধিক শর্ত যোগ করতে পারেন।
RaRdEvA

@ আরআরডিএভিএ এটি পারফরম্যান্সের জন্য দুর্দান্ত নয় যদিও এটি correlated subqueryফলাফলের প্রতিটি একক সারির জন্য আরও বেশি করে সারি স্ক্যান করে চালিয়ে যায়। এটি চলমান মোট রাখে না এবং উইন্ডো ফাংশনগুলির মতো একবার স্ক্যান করে।
দাভোস

1
@ ডেভস আপনি ঠিক বলেছেন আপনি যদি এটি ব্যবহার করেন তবে এটি 100,000 রেকর্ডের চেয়ে খুব ধীর হয়ে যায়।
RaRdEvA

2

এই চমৎকার পোস্টের একটি অনেক দ্রুত কোটে বাস্তবায়ন উপলব্ধ: http://weblogs.sqlteam.com/mladenp/archive/2009/07/28/SQL-Server-2005-Fast-Running-Totals.aspx

এই থ্রেডের সমস্যাটি এভাবে প্রকাশ করা যেতে পারে:

    DECLARE @RT INT
    SELECT @RT = 0

    ;
    WITH  abcd
            AS ( SELECT TOP 100 percent
                        id
                       ,SomeNumt
                       ,MySum
                       order by id
               )
      update abcd
      set @RT = MySum = @RT + SomeNumt
      output inserted.*


1

টেবিলটি তৈরি হয়ে গেলে -

select 
    A.id, A.SomeNumt, SUM(B.SomeNumt) as sum
    from @t A, @t B where A.id >= B.id
    group by A.id, A.SomeNumt

order by A.id

1

উপরে (প্রাক-এসকিউএল 12) আমরা এর উদাহরণ দেখতে পাই: -

SELECT
    T1.id, SUM(T2.id) AS CumSum
FROM 
    #TMP T1
    JOIN #TMP T2 ON T2.id < = T1.id
GROUP BY
    T1.id

আরো দক্ষ...

SELECT
    T1.id, SUM(T2.id) + T1.id AS CumSum
FROM 
    #TMP T1
    JOIN #TMP T2 ON T2.id < T1.id
GROUP BY
    T1.id

1

আপনি প্রগতিশীল গণনার জন্য এই সাধারণ ক্যোয়ারীটি ব্যবহার করতে পারেন:

select 
   id
  ,SomeNumt
  ,sum(SomeNumt) over(order by id ROWS between UNBOUNDED PRECEDING and CURRENT ROW) as CumSrome
from @t

0

এটা চেষ্টা কর

select 
    t.id,
    t.SomeNumt, 
    sum(t.SomeNumt) Over (Order by t.id asc Rows Between Unbounded Preceding and Current Row) as cum
from 
    @t t 
group by
    t.id,
    t.SomeNumt
order by
    t.id asc;

এটি এসকিউএল সার্ভার ২০১২ এবং এর সাথে কাজ করে, ২০০৮ এর উইন্ডো ফাংশনগুলির জন্য সীমিত সমর্থন রয়েছে।
পিটার স্মিট

0

এটা চেষ্টা কর:

CREATE TABLE #t(
 [name] varchar NULL,
 [val] [int] NULL,
 [ID] [int] NULL
) ON [PRIMARY]

insert into #t (id,name,val) values
 (1,'A',10), (2,'B',20), (3,'C',30)

select t1.id, t1.val, SUM(t2.val) as cumSum
 from #t t1 inner join #t t2 on t1.id >= t2.id
 group by t1.id, t1.val order by t1.id

0

এসকিউএল সলিউশন উইচটি "পাউন্ড বিহীন পূর্বনির্ধারিত এবং বর্তমান সারি" এর সাথে সংযুক্ত করে এবং "এসইএম" আমি যা অর্জন করতে চেয়েছিলাম ঠিক তা করেছে did তোমাকে অনেক ধন্যবাদ!

এটি যদি কাউকে সহায়তা করতে পারে তবে এখানে আমার মামলা ছিল। যখনই কোনও নির্মাতাকে "কিছু প্রস্তুতকারক" (উদাহরণ) হিসাবে পাওয়া যায় আমি কলামে +1 করতে চেয়েছিলাম ulate যদি না হয় তবে কোনও ইনক্রিমেন্ট নয় তবে আগের ইনক্রিমেন্টের ফলাফল দেখান।

সুতরাং এসকিউএল এই টুকরা:

SUM( CASE [rmaker] WHEN 'Some Maker' THEN  1 ELSE 0 END) 
OVER 
(PARTITION BY UserID ORDER BY UserID,[rrank] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Cumul_CNT

আমাকে এরকম কিছু পাওয়ার অনুমতি দিল:

User 1  Rank1   MakerA      0  
User 1  Rank2   MakerB      0  
User 1  Rank3   Some Maker  1  
User 1  Rank4   Some Maker  2  
User 1  Rank5   MakerC      2
User 1  Rank6   Some Maker  3  
User 2  Rank1   MakerA      0  
User 2  Rank2   SomeMaker   1  

উপরের ব্যাখ্যা: এটি 0 দিয়ে "কিছু প্রস্তুতকারকের" গণনা শুরু করে, কিছু নির্মাতা পাওয়া যায় এবং আমরা +1 করি। ব্যবহারকারীর 1 এর জন্য, মেকেরিকে সন্ধান করা হয়েছে সুতরাং আমরা +1 করব না তবে এর পরিবর্তে কিছু মেকারের উল্লম্ব গণনাটি পরবর্তী সারিতে 2 পর্যন্ত আটকে থাকবে। পার্টিশনটি ব্যবহারকারীর দ্বারা হয় তাই আমরা যখন ব্যবহারকারী পরিবর্তন করি তখন ক্রমসংখ্যা শূন্যে ফিরে আসে।

আমি কর্মক্ষেত্রে আছি, আমি এই উত্তরের কোনও যোগ্যতা চাই না, কেবল আপনাকে ধন্যবাদ বলুন এবং কেউ যদি একই পরিস্থিতিতে থাকে তবে আমার উদাহরণটি দেখান। আমি সুম এবং পার্টিশন একত্রিত করার চেষ্টা করছিলাম তবে কাজটি সম্পন্ন করে আশ্চর্যজনক সিনট্যাক্স "র্যান্ডস বিউন্ডউইন্ড বিউন্ডেড প্রাইসিডিং অ্যান্ড ক্রু র"।

ধন্যবাদ! Groaker


0

কোনও ব্যক্তির জন্য কোনও প্রকারের যোগসুলভ বেতন ব্যবহার না করে অনুসরণ করে অনুসরণ করুন:

SELECT * , (
  SELECT SUM( salary ) 
  FROM  `abc` AS table1
  WHERE table1.ID <=  `abc`.ID
    AND table1.name =  `abc`.Name
) AS cum
FROM  `abc` 
ORDER BY Name

0

উদাহরণস্বরূপ: যদি আপনার দুটি কলামযুক্ত একটি সারণী থাকে তবে একটি আইডি এবং দ্বিতীয়টি নম্বর এবং সংযোজক যোগফলটি খুঁজতে চান।

SELECT ID,Number,SUM(Number)OVER(ORDER BY ID) FROM T
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.