গণনা সহ মোট চলমান?


34

শিরোনামের পরামর্শ অনুসারে টি-এসকিউএল এ চলমান মোট পেতে আমার কিছুটা সহায়তা দরকার। সমস্যাটি হ'ল আমার যে যোগফলটি করতে হবে তা হ'ল একটি গণনার যোগফল:

sum(count (distinct (customers))) 

বলুন আমি যদি একাই গণনা চালাতাম তবে ফলাফলটি হবে:

Day | CountCustomers
----------------------
5/1  |      1
5/2  |      0
5/3  |      5

যোগফলটির সাথে আমার আউটপুট দরকার:

Day | RunningTotalCustomers
----------------------
5/1  |      1
5/2  |      1
5/3  |      6

coalesceপদ্ধতিটি ব্যবহারের আগে আমি মোট রান চালিয়েছি , তবে কখনই একটি গণনা সহ নয়। আমার এখন গণনা আছে এখন এটি কীভাবে করবেন তা আমি নিশ্চিত নই।


2
এসকিউএল সার্ভারের কোন সংস্করণ দয়া করে? আপনি কি ডেটার ক্ষেত্রটি ভাগ করতে পারেন - আমরা কি 1000 সারি, এক মিলিয়ন, এক বিলিয়ন সম্পর্কে কথা বলছি? এটি কি কেবলমাত্র এই দুটি কলাম, বা আপনি আমাদের জন্য স্কিমাকে সহজ করেছেন? অবশেষে, Dayএকটি কী এবং মানগুলি কি সামঞ্জস্যপূর্ণ?
অ্যারন বারট্র্যান্ড

আমি মোট (বিদ্রূপাত্মক আপডেট বনাম হাইব্রীড Recursive কোটে বনাম কার্সার) চলমান সম্পর্কে একটি ব্যাপক ব্লগ তৈরি করেছেন: ienablemuch.com/2012/05/... আমি চলমান মোট যে ব্যবহারসমূহ বিশুদ্ধ সেট-ভিত্তিক পদ্ধতির কর্মক্ষমতা হতে কিছুই নয় অন্তর্ভুক্ত করা হয়নি পছন্দসই: sqlblog.com/blogs/adam_machanic/archive/2006/07/12/…
মাইকেল বুয়েন

উত্তর:


53

আপনি তুলনা করতে পারেন কয়েকটি পদ্ধতি এখানে। প্রথমে কিছু ডামি ডেটা সহ একটি টেবিল সেট আপ করা যাক। আমি এটিকে sys.all_collines থেকে একগুচ্ছ এলোমেলো ডেটা দিয়ে পপুলেট করছি। ওয়েল, এটি এলোমেলো এক ধরণের - আমি নিশ্চিত করছি যে তারিখগুলি সুসংগত (যা উত্তরগুলির জন্য কেবলমাত্র গুরুত্বপূর্ণ)।

CREATE TABLE dbo.Hits(Day SMALLDATETIME, CustomerID INT);

CREATE CLUSTERED INDEX x ON dbo.Hits([Day]);

INSERT dbo.Hits SELECT TOP (5000) DATEADD(DAY, r, '20120501'),
  COALESCE(ASCII(SUBSTRING(name, s, 1)), 86)
FROM (SELECT name, r = ROW_NUMBER() OVER (ORDER BY name)/10,
       s = CONVERT(INT, RIGHT(CONVERT(VARCHAR(20), [object_id]), 1))
FROM sys.all_columns) AS x;

SELECT 
  Earliest_Day   = MIN([Day]), 
  Latest_Day     = MAX([Day]), 
  Unique_Days    = DATEDIFF(DAY, MIN([Day]), MAX([Day])) + 1, 
  Total_Rows     = COUNT(*)
FROM dbo.Hits;

ফলাফল:

Earliest_Day         Latest_Day           Unique_Days  Total_Days
-------------------  -------------------  -----------  ----------
2012-05-01 00:00:00  2013-09-13 00:00:00  501          5000

ডেটা দেখতে (5000 সারি) এর মতো দেখায় - তবে সংস্করণ এবং বিল্ড # এর উপর নির্ভর করে আপনার সিস্টেমে কিছুটা আলাদা দেখাবে

Day                  CustomerID
-------------------  ---
2012-05-01 00:00:00  95
2012-05-01 00:00:00  97
2012-05-01 00:00:00  97
2012-05-01 00:00:00  117
2012-05-01 00:00:00  100
...
2012-05-02 00:00:00  110
2012-05-02 00:00:00  110
2012-05-02 00:00:00  95
...

এবং চলমান মোট ফলাফলের মতো দেখতে হবে (501 সারি):

Day                  c   rt
-------------------  --  --
2012-05-01 00:00:00  6   6
2012-05-02 00:00:00  5   11
2012-05-03 00:00:00  4   15
2012-05-04 00:00:00  7   22
2012-05-05 00:00:00  6   28
...

সুতরাং যে পদ্ধতিগুলির সাথে আমি তুলনা করতে চলেছি সেগুলি হ'ল:

  • "স্ব-যোগদান" - সেট-ভিত্তিক পিউরিস্ট পদ্ধতির
  • "তারিখগুলির সাথে পুনরাবৃত্তির সিটিই" - এটি সংবিধানের তারিখগুলিতে নির্ভর করে (কোনও ফাঁক নেই)
  • "সারি_সংখ্যার সাথে পুনরাবৃত্ত সিটিই" - উপরের মত তবে ধীরে ধীরে, ROW_NUMBER এ ভরসা করে
  • "টেম্প টেবিল সহ পুনরাবৃত্ত সিটিই" - পরামর্শ হিসাবে মাইকের উত্তর থেকে চুরি হয়েছে
  • "কৌতূহলী আপডেট" যা অসমর্থিত এবং সংজ্ঞায়িত আচরণের প্রতিশ্রুতি দেয় না তা বেশ জনপ্রিয় বলে মনে হয়
  • "কার্সার"
  • এসকিউএল সার্ভার 2012 নতুন উইন্ডোটিং কার্যকারিতা ব্যবহার করে

স্ব-যোগ

লোকেরা আপনাকে কর্সার থেকে দূরে থাকার জন্য সতর্ক করার সময় এইভাবেই আপনাকে এটি করতে বলবে, কারণ "সেট ভিত্তিক সর্বদা দ্রুত হয়।" কিছু সাম্প্রতিক পরীক্ষায় আমি খুঁজে পেয়েছি যে কার্সার এই সমাধানটিকে দ্রুত চালায়।

;WITH g AS 
(
  SELECT [Day], c = COUNT(DISTINCT CustomerID) 
    FROM dbo.Hits
    GROUP BY [Day]
)
SELECT g.[Day], g.c, rt = SUM(g2.c)
  FROM g INNER JOIN g AS g2
  ON g.[Day] >= g2.[Day]
GROUP BY g.[Day], g.c
ORDER BY g.[Day];

তারিখের সাথে পুনরাবৃত্ত cte

অনুস্মারক - এটি সংশ্লেষের তারিখগুলিতে (কোনও ফাঁক নেই) পুনরাবৃত্তির 10000 স্তর পর্যন্ত নির্ভর করে এবং আপনি যে সীমাটি আগ্রহী তা শুরু করার তারিখটি জানেন (অ্যাঙ্কর সেট করতে)। আপনি অবশ্যই একটি সাবকিউরিটি ব্যবহার করে গতিময়ভাবে অ্যাঙ্কর সেট করতে পারেন, তবে আমি জিনিসগুলি সহজ রাখতে চেয়েছিলাম।

;WITH g AS 
(
  SELECT [Day], c = COUNT(DISTINCT CustomerID) 
    FROM dbo.Hits
    GROUP BY [Day]
), x AS
(
    SELECT [Day], c, rt = c
        FROM g
        WHERE [Day] = '20120501'
    UNION ALL
    SELECT g.[Day], g.c, x.rt + g.c
        FROM x INNER JOIN g
        ON g.[Day] = DATEADD(DAY, 1, x.[Day])
)
SELECT [Day], c, rt
    FROM x
    ORDER BY [Day]
    OPTION (MAXRECURSION 10000);

সারি_সংখ্যার সাথে পুনরাবৃত্ত সিটি

সারি_সংখ্যার গণনা এখানে কিছুটা ব্যয়বহুল। আবার এটি সর্বোচ্চ স্তরকে 10000 পুনরাবৃত্তি সমর্থন করে, তবে আপনাকে অ্যাঙ্কর বরাদ্দ করার দরকার নেই।

;WITH g AS 
(
  SELECT [Day], rn = ROW_NUMBER() OVER (ORDER BY DAY), 
    c = COUNT(DISTINCT CustomerID) 
    FROM dbo.Hits
    GROUP BY [Day]
), x AS
(
    SELECT [Day], rn, c, rt = c
        FROM g
        WHERE rn = 1
    UNION ALL
    SELECT g.[Day], g.rn, g.c, x.rt + g.c
        FROM x INNER JOIN g
        ON g.rn = x.rn + 1
)
SELECT [Day], c, rt
    FROM x
    ORDER BY [Day]
    OPTION (MAXRECURSION 10000);

টেম্প টেবিল সহ পুনরাবৃত্ত cte

মাইকের উত্তর থেকে চুরি করা, পরামর্শ হিসাবে এটি পরীক্ষাগুলিতে অন্তর্ভুক্ত করার জন্য।

CREATE TABLE #Hits
(
  rn INT PRIMARY KEY,
  c INT,
  [Day] SMALLDATETIME
);

INSERT INTO #Hits (rn, c, Day)
SELECT ROW_NUMBER() OVER (ORDER BY DAY),
       COUNT(DISTINCT CustomerID),
       [Day]
FROM dbo.Hits
GROUP BY [Day];

WITH x AS
(
    SELECT [Day], rn, c, rt = c
        FROM #Hits as c
        WHERE rn = 1
    UNION ALL
    SELECT g.[Day], g.rn, g.c, x.rt + g.c
        FROM x INNER JOIN #Hits as g
        ON g.rn = x.rn + 1
)
SELECT [Day], c, rt
    FROM x
    ORDER BY [Day]
    OPTION (MAXRECURSION 10000);

DROP TABLE #Hits;

উদ্দীপনা আপডেট

আবার আমি কেবল এটি সম্পূর্ণতার জন্য অন্তর্ভুক্ত করছি; আমি ব্যক্তিগতভাবে এই সমাধানটির উপর নির্ভর করব না, যেহেতু আমি অন্য উত্তরে উল্লেখ করেছি, এই পদ্ধতিটি মোটেই কাজ করার গ্যারান্টিযুক্ত নয় এবং এটি এসকিউএল সার্ভারের ভবিষ্যতের সংস্করণে পুরোপুরি ভেঙে যেতে পারে। (আমি সূচক পছন্দের জন্য একটি ইঙ্গিত ব্যবহার করে এসকিউএল সার্ভারকে আমার যে আদেশটি চাই তা মানতে বাধ্য করার জন্য যথাসাধ্য চেষ্টা করছি।)

CREATE TABLE #x([Day] SMALLDATETIME, c INT, rt INT);
CREATE UNIQUE CLUSTERED INDEX x ON #x([Day]);

INSERT #x([Day], c) 
    SELECT [Day], c = COUNT(DISTINCT CustomerID) 
    FROM dbo.Hits
    GROUP BY [Day]
    ORDER BY [Day];

DECLARE @rt1 INT;
SET @rt1 = 0;

UPDATE #x
SET @rt1 = rt = @rt1 + c
FROM #x WITH (INDEX = x);

SELECT [Day], c, rt FROM #x ORDER BY [Day];

DROP TABLE #x;

কার্সার

"সাবধান, এখানে কার্সার রয়েছে! কার্সাররা মন্দ! আপনার যেকোন মূল্যে কার্সার এড়ানো উচিত!" না, এটি আমি কথা বলছি না, এটি কেবল প্রচুর শুনতে পাওয়া যায় hear জনপ্রিয় মতামতের বিপরীতে, কিছু ক্ষেত্রে রয়েছে যেখানে কার্সারগুলি উপযুক্ত।

CREATE TABLE #x2([Day] SMALLDATETIME, c INT, rt INT);
CREATE UNIQUE CLUSTERED INDEX x ON #x2([Day]);

INSERT #x2([Day], c) 
    SELECT [Day], COUNT(DISTINCT CustomerID) 
    FROM dbo.Hits
    GROUP BY [Day]
    ORDER BY [Day];

DECLARE @rt2 INT, @d SMALLDATETIME, @c INT;
SET @rt2 = 0;

DECLARE c CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
  FOR SELECT [Day], c FROM #x2 ORDER BY [Day];

OPEN c;

FETCH NEXT FROM c INTO @d, @c;

WHILE @@FETCH_STATUS = 0
BEGIN
  SET @rt2 = @rt2 + @c;
  UPDATE #x2 SET rt = @rt2 WHERE [Day] = @d;
  FETCH NEXT FROM c INTO @d, @c;
END

SELECT [Day], c, rt FROM #x2 ORDER BY [Day];

DROP TABLE #x2;

এসকিউএল সার্ভার 2012

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

;WITH g AS 
(
  SELECT [Day], c = COUNT(DISTINCT CustomerID) 
    FROM dbo.Hits
    GROUP BY [Day]
)
SELECT g.[Day], c, 
  rt = SUM(c) OVER (ORDER BY [Day] ROWS UNBOUNDED PRECEDING)
FROM g
ORDER BY g.[Day];

পারফরম্যান্স তুলনা

আমি প্রতিটি পন্থা গ্রহণ করেছি এবং নিম্নলিখিতটি ব্যবহার করে এটি একটি ব্যাচ জড়িয়েছি:

SELECT SYSUTCDATETIME();
GO
DBCC DROPCLEANBUFFERS;DBCC FREEPROCCACHE;
-- query here
GO 10
SELECT SYSUTCDATETIME();

মিলিসেকেন্ডে মোট সময়কালের ফলাফল এখানে রয়েছে (মনে রাখবেন এটিতে প্রতিবারের মতো ডিবিসিসি কমান্ডও অন্তর্ভুক্ত রয়েছে):

method                          run 1     run 2
-----------------------------   --------  --------
self-join                        1296 ms   1357 ms -- "supported" non-SQL 2012 winner
recursive cte with dates         1655 ms   1516 ms
recursive cte with row_number   19747 ms  19630 ms
recursive cte with #temp table   1624 ms   1329 ms
quirky update                     880 ms   1030 ms -- non-SQL 2012 winner
cursor                           1962 ms   1850 ms
SQL Server 2012                   847 ms    917 ms -- winner if SQL 2012 available

আর আমি এটি আবার ডিবিসিসির আদেশ ছাড়াই করেছি:

method                          run 1     run 2
-----------------------------   --------  --------
self-join                        1272 ms   1309 ms -- "supported" non-SQL 2012 winner
recursive cte with dates         1247 ms   1593 ms
recursive cte with row_number   18646 ms  18803 ms
recursive cte with #temp table   1340 ms   1564 ms
quirky update                    1024 ms   1116 ms -- non-SQL 2012 winner
cursor                           1969 ms   1835 ms
SQL Server 2012                   600 ms    569 ms -- winner if SQL 2012 available

কেবলমাত্র একটি কাঁচা পুনরাবৃত্তি পরিমাপ করে ডিবিসিসি এবং লুপ উভয়কেই সরিয়ে ফেলা হচ্ছে:

method                          run 1     run 2
-----------------------------   --------  --------
self-join                         313 ms    242 ms
recursive cte with dates          217 ms    217 ms
recursive cte with row_number    2114 ms   1976 ms
recursive cte with #temp table     83 ms    116 ms -- "supported" non-SQL 2012 winner
quirky update                      86 ms     85 ms -- non-SQL 2012 winner
cursor                           1060 ms    983 ms
SQL Server 2012                    68 ms     40 ms -- winner if SQL 2012 available

অবশেষে, আমি উত্স টেবিলের মধ্যে সারি গণনাটি 10 ​​দ্বারা গুণিত করেছি (শীর্ষে 50000 এ পরিবর্তন এবং ক্রস যোগ হিসাবে অন্য সারণী যুক্ত করা)। এর ফলাফল, কোনও একক পুনরাবৃত্তি কোনও ডিবিসিসি আদেশ ছাড়াই (কেবল সময়ের স্বার্থে):

method                           run 1      run 2
-----------------------------    --------   --------
self-join                         2401 ms    2520 ms
recursive cte with dates           442 ms     473 ms
recursive cte with row_number   144548 ms  147716 ms
recursive cte with #temp table     245 ms     236 ms -- "supported" non-SQL 2012 winner
quirky update                      150 ms     148 ms -- non-SQL 2012 winner
cursor                            1453 ms    1395 ms
SQL Server 2012                    131 ms     133 ms -- winner

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


ডেমো

আমি একটি স্ক্যালফিল্ড যুক্ত করেছি । ফলাফল:

এখানে চিত্র বর্ণনা লিখুন


উপসংহার

আমার পরীক্ষায়, পছন্দটি হ'ল:

  1. এসকিউএল সার্ভার 2012 পদ্ধতি, যদি আমার এসকিউএল সার্ভার 2012 উপলব্ধ থাকে।
  2. যদি এসকিউএল সার্ভার 2012 উপলভ্য না হয় এবং আমার তারিখগুলি সুসংগত হয় তবে আমি তারিখের পদ্ধতি সহ পুনরাবৃত্ত cte সাথে যেতে পারি।
  3. যদি না ১ বা ২ প্রযোজ্য হয় তবে আমি আচরণটি নথিভুক্ত ও গ্যারান্টিযুক্ত হওয়ার কারণে পারফরম্যান্সটি কাছাকাছি থাকা সত্ত্বেও উদ্দীপক আপডেটের সাথে স্ব-যোগদানের সাথে যাব। আমি ভবিষ্যতের সামঞ্জস্যতা সম্পর্কে কম চিন্তিত কারণ আশা করি যদি উদ্বেগজনক আপডেটটি ভেঙে যায় তবে আমি ইতিমধ্যে আমার সমস্ত কোডকে ১: :-) রূপান্তর করার পরে এটি হবে will

তবে আবার, আপনার এটি আপনার স্কিমা এবং ডেটার বিরুদ্ধে পরীক্ষা করা উচিত। যেহেতু এটি তুলনামূলকভাবে নিম্ন সারি গণনার সাথে একটি স্বীকৃত পরীক্ষা ছিল, এটি বায়ুতেও খুব দূরে থাকতে পারে। আমি বিভিন্ন স্কিমা এবং সারি গণনা সহ অন্যান্য পরীক্ষা করেছি এবং পারফরম্যান্স হিউরিস্টিকসটি একেবারেই আলাদা ছিল ... এজন্য আমি আপনার মূল প্রশ্নটিতে অনেকগুলি ফলো-আপ প্রশ্ন জিজ্ঞাসা করেছি।


হালনাগাদ

আমি এখানে এই সম্পর্কে আরও ব্লগ করেছি:

মোট রান করার জন্য সেরা পন্থা - এসকিউএল সার্ভার ২০১২-এর জন্য আপডেট


1

এটি আপাতদৃষ্টিতে সর্বোত্তম সমাধান

DECLARE @dailyCustomers TABLE (day smalldatetime, CountCustomers int, RunningTotal int)

DECLARE @RunningTotal int

SET @RunningTotal = 0

INSERT INTO @dailyCustomers 
SELECT day, CountCustomers, null
FROM Sales
ORDER BY day

UPDATE @dailyCustomers
SET @RunningTotal = RunningTotal = @RunningTotal + CountCustomers
FROM @dailyCustomers

SELECT * FROM @dailyCustomers

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

এটি একটি স্ব যোগদানের সাথে বা নেস্টেড সাবকোয়ারি দ্বারাও করা যেতে পারে তবে এই বিকল্পগুলি প্রায় ভাল সম্পাদন করে না। এছাড়াও সম্ভবত আপনি এই বিকল্পগুলির সাথে কিছু স্পুলিং বা ওয়ার্ক টেবিলের সাহায্যে টেম্পিডবিতে আঘাত হানাবেন।

3
কেবল সচেতন থাকুন যে এই "কৌতুকপূর্ণ আপডেট" পদ্ধতিটি কাজ করার গ্যারান্টিযুক্ত নয় - এই বাক্য গঠনটি অসমর্থিত এবং এর আচরণটি পূর্বনির্ধারিত, এবং এটি ভবিষ্যতের সংস্করণ, হট ফিক্স বা সার্ভিস প্যাকে ভেঙে যেতে পারে। সুতরাং হ্যাঁ এটি কয়েকটি সমর্থিত বিকল্পের চেয়ে দ্রুত, এটি সম্ভাব্য ভবিষ্যতের সামঞ্জস্যতা ব্যয়।
অ্যারন বারট্র্যান্ড

6
এই পদ্ধতির প্রচুর সতর্কতা রয়েছে যা জেফ মোডেন কোথাও লিখেছেন। dayউদাহরণস্বরূপ আপনার একটি ক্লাস্টার ইনডেক্স থাকা উচিত ।
মার্টিন স্মিথ

2
@ মার্টিনস্মিথ এটি sqlservercentral.com এ একটি খুব বড় নিবন্ধ (লেখকের পৃষ্ঠায় যান এবং তার 'তর্কগুলি আপডেটের নিবন্ধগুলি সন্ধান করুন)।
ফ্যাব্রিকিও আরাউজো

-2

আরও একটি উপায়, ব্যয়বহুল, কিন্তু সংস্করণ স্বাধীন। এটি টেম্প টেবিল বা ভেরিয়েবল ব্যবহার করে না।

select T.dday, T.CustomersByDay + 
    (select count(A.customer) from NewCustomersByDate A 
      where A.dday < T.dday) as TotalCustomerTillNow 
from (select dday, count(customer) as CustomersByDay 
        from NewCustomersByDate group by dday) T 

2
এটি ভাল নয়, এটি খুব ধীর। এমনকি আপনার মাত্র 100 টি সারি রয়েছে, এটি 5,050 বার টেবিলের মধ্যে পিং-পং পড়বে। 200 সারি, 20,100 বার। কেবলমাত্র 1000 সারি সহ, এটি স্প্ল্যাশিয়ালি লাফিয়ে 500,500-এ পৌঁছে যায় sqlblog.com/blogs/adam_machanic/archive/2006/07/12/…
মাইকেল বুয়েন

আমি এটি পোস্ট করার পরে আপনার ব্লগের লিঙ্কটি দেখেছি, এখন আমি এটি দেখতে একটি খুব খারাপ ধারণা, ধন্যবাদ!
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.