YetAnotherForum
სალამი სტუმარს ძებნა | აქტიური თემები | შესვლა | რეგისტრაცია

ფავორიტებში დამატება
Sql Query Help
achiko Offline
#1 Posted : Sunday, September 12, 2010 6:58:06 PM

Rank: Member

Medals:

Groups: Registered
Joined: 6/20/2010
Posts: 12
Points: 36
Location: Georgia

Thanks: 0 times
Was thanked: 1 time(s) in 1 post(s)
-- მაქვს მარტივი ცხრილი სადაც იწერება სალაროში შეტანა - გამოტანები მომხმარებლის მიხედვით

DECLARE @tblCash TABLE
(
UserId INT, -- მომხმარებელი
Amount MONEY, -- თანხა
Operation CHAR(1) -- ოპერაციის ტიპი А - შემოტანა О - გატანა
)

INSERT INTO @tblCash VALUES (1, 2.00, 'A')
INSERT INTO @tblCash VALUES (2, 178.00, 'O')
INSERT INTO @tblCash VALUES (1, 2.00, 'A')
INSERT INTO @tblCash VALUES (2, 17.00, 'O')
INSERT INTO @tblCash VALUES (2, 2.00, 'O')
INSERT INTO @tblCash VALUES (3, 1.00, 'O')
INSERT INTO @tblCash VALUES (1, 2.00, 'O')
INSERT INTO @tblCash VALUES (3, 1.00, 'A')
INSERT INTO @tblCash VALUES (2, 15.00, 'A')
INSERT INTO @tblCash VALUES (1, 13.00, 'O')



-- მინდა ამ ცხრილიდან მონაცემების გამოტანა შემდეგნაირად

-- 1. მომხმარებელი | შემოტანილი თანხა | გატანილი თანხა


- ქუერი რომელიც მე დავწრე ... მაგრამ მგონია რომ უფრო ლამაზად შეიძლება ამის დაწერა. იქნებ მირჩიოთ როგორ ჯობია ?

;WITH A AS
(
-- ყველა შემოტანილი თანხა დაგრუპებული მომხარებლის ID - ის მიხედვით
SELECT UserId, SUM(Amount) AS AmountIn FROM @tblCash WHERE Operation = 'A'
GROUP BY UserId

),B AS
(
-- ყველა გატანილი თანხა დაგრუპებული მომხარებლის ID - ის მიხედვით
SELECT UserId, SUM(Amount) AS AmountOut FROM @tblCash WHERE Operation = 'O'
GROUP BY UserId

)

-- ამის შემდეგ ვაკეთებ Join - ს Table A სა და B - ს შორის

SELECT A.UserId, A.AmountIn,B.AmountOut, (A.AmountIn - B.AmountOut) AS Balanse FROM A
INNER JOIN B ON A.UserId = B.UserId

Sponsor  
 
Apex ltd. http://www.apex.ge
vajaGM Offline
#2 Posted : Monday, September 13, 2010 9:09:20 AM

Rank: Administration

Medals:

Groups: Administrators
Joined: 10/20/2012
Posts: 106
Points: 327
Location: Tbilisi

Thanks: 0 times
Was thanked: 0 time(s) in 0 post(s)
უმჯობესია ეს ყველაფერი ასე გადაწეროთ :
BB კოდი:

WITH ct AS (SELECT     UserId, Operation, CASE Operation WHEN 'A' THEN SUM(Amount) ELSE 0 END AS AmountIn,
                                                 CASE Operation WHEN 'A' THEN 0 ELSE SUM(Amount) END AS AmountOut
                          FROM          @tblCash
                          GROUP BY UserId, Operation)
    SELECT     UserId, SUM(AmountIn) AS AmountIn, SUM(AmountOut) AS AmountOut, SUM(AmountIn) - SUM(AmountOut) AS Balanse
     FROM         ct AS a
     GROUP BY UserId


რატომ? იმიტომ, რომ:
1. თქვენს შემთხვევაში მონაცემთა ბაზას მიმართავთ ორჯერ, ორჯერ კრიბავთ იქედან საჭირო მონაცემებს, შემდეგ კი JOIN -ს აკეთებთ.
უბრალოდ შეადარეთ ამ სელექტების EXECUTION PLAN და ყველაფერს მიხვდებით, თუ რამდენად დიდია მათ შორის განსხვავება.
2. თქვენი სელექტის მიხედვით თუ რომელიმე UserId-ზე არ არის შესრულებული შემოსავალი(ან გასავალი), მაშინ თქვენ მიიღებთ არასწორ პასუხს და ეს უსერი საერთოდ არ მოგიხვდებათ სიაში.
ქუოტა (Quote):
vajaGM Offline
#3 Posted : Monday, September 13, 2010 11:06:20 AM

Rank: Administration

Medals:

Groups: Administrators
Joined: 10/20/2012
Posts: 106
Points: 327
Location: Tbilisi

Thanks: 0 times
Was thanked: 0 time(s) in 0 post(s)
ისე თუ მაინცდამაინც სილამაზეს დიდი მნიშვნელობა აქვს Confused შეგიძლია ასეც გადაწერო :
BB კოდი:
SELECT UserId, [A] AS AmountIn, [O] AS AmountOut, [A]-[O] AS Balanse
FROM @tblCash AS s
PIVOT
(
SUM(Amount)
FOR Operation IN ([A], [O])
) AS p;
ქუოტა (Quote):
achiko Offline
#4 Posted : Monday, September 13, 2010 6:45:08 PM

Rank: Member

Medals:

Groups: Registered
Joined: 6/20/2010
Posts: 12
Points: 36
Location: Georgia

Thanks: 0 times
Was thanked: 1 time(s) in 1 post(s)
დიდი მადლობა ბოლო ქუერი მართლაც ლამაზია :)
achiko Offline
#5 Posted : Sunday, February 13, 2011 8:33:05 PM

Rank: Member

Medals:

Groups: Registered
Joined: 6/20/2010
Posts: 12
Points: 36
Location: Georgia

Thanks: 0 times
Was thanked: 1 time(s) in 1 post(s)
ახლა გავაგრძელებ ამ ქუერის ისტორიას

თავიდან დავიწყე ლმაზი ქუერით :)

ქუოტა (Quote):
SELECT UserId, [A] AS AmountIn, [O] AS AmountOut, [A]-[O] AS Balanse
FROM @tblCash AS s
PIVOT
(
SUM(Amount)
FOR Operation IN ([A], [O])
) AS p;


დაახლოებით 400 000 ტრანზაქციაზე შესრულების დრო დაწერა 14 წამი...

ამის შემდეგ გადავწყვიტე გამომეყენებინა მეორე მაგალითი

ქუოტა (Quote):
WITH ct AS (SELECT UserId, Operation, CASE Operation WHEN 'A' THEN SUM(Amount) ELSE 0 END AS AmountIn,
CASE Operation WHEN 'A' THEN 0 ELSE SUM(Amount) END AS AmountOut
FROM @tblCash
GROUP BY UserId, Operation)
SELECT UserId, SUM(AmountIn) AS AmountIn, SUM(AmountOut) AS AmountOut, SUM(AmountIn) - SUM(AmountOut) AS Balanse
FROM ct AS a
GROUP BY UserId



შესრულების დრო 1 წამი. მეორე გაშვებაზე წამზე ნაკლები ...

ჩემი კითხვა მდგომარეობს შემდეგში რატო იძლევა ამდენ სხვაობას შესრულების დროში ეს ორი ქუერი ? IN ოპერაციის გამო ?

ეს ისე მომავლისთვის მაინტერესებს სად არის მძიმე ოპერაცია ? პირველ კოდში ?

დიდი მადლობა წინასწარ.


vajaGM Offline
#6 Posted : Wednesday, February 23, 2011 3:30:42 PM

Rank: Administration

Medals:

Groups: Administrators
Joined: 10/20/2012
Posts: 106
Points: 327
Location: Tbilisi

Thanks: 0 times
Was thanked: 0 time(s) in 0 post(s)
არა მგონია, რომ ამ ორ ვარიანტს შორის რაიმე არსებითი სხვაობა იყოს.

წერთ, რომ მეორე (pivot) ვარიანტის შესრულებისას:
ქუოტა (Quote):
დაახლოებით 400 000 ტრანზაქციაზე შესრულების დრო დაწერა 14 წამი...


საინტერესოა რა დრო დასჭირდა და მას მეორედ შესრულების დროს? ისევ 14 წამი თუ 0 წამი?


და კიდევ ერთი:

რომ შეგესრულებინათ პირველად მეორე (with) ვარიანტი, რა დრო დასჭირდებოდა მის პირველ შესრულებას?
0 წამი თუ 14 წამი?

ის, რომ მეორე შესრულებას დრო უმცირესი სჭირდება არის sql-ის ქეშირების თვისების დამსახურება...


დავამატებდი ასევე, რომ :

1. 400000 ჩანაწერზე წარმოუდგენელია თუნდაც ჩვეულებრივ, არაფრით გამორჩეულ კომპიუტერსაც კი 14 წამი დასჭირდეს ამ ოპერაციის შესრულებას.
მითუმეტეს, რომ თქვენს შემთხვევაში სერვერს დასჭირდა ეს დრო...

სავარაუდოდ ამ დროს სერვერზე ხდებოდა რაღაც სხვა ოპერაცია, რომელიც ზღუდავდა ამ ოპერაციის შესრულებას.

2. თუ შესრულების დრო არის მიუღებელი, მაშინ აუცილებელია შექმნათ ინდექსი UserId და Operation სვეტებისათვის, რაც მინუმუმამდე დაიყვანს შესრულების დროს.

ქუოტა (Quote):
Users browsing this topic
Guest (2)
ფავორიტებში დამატება
Forum Jump  
თქვენ არ შეგიძლიათ დაწეროთ ახალი თემა ამ ფორუმში.
თქვენ არ შეგიძლიათ გასცეთ პასუხი, თემას, ამ ფორუმში .
თქვენ არ შეგიძლიათ წაშალოთ თქვენი პოსტი ამ ფორუმში.
თქვენ არ შეგიძლიათ ჩაასწოროთ თქვენი პოსტი ამ ფორუმში.
თქვენ არ შეგიძლიათ შექმნათ გამოკითხვა ამ ფორუმში.
თქვენ არ შეგიძლიათ ხმის მიცემა ამ ფოუმში.

YAFVision Theme by Jaben Cargman (Tiny Gecko)
Powered by YAF | YAF © 2003-2009, Yet Another Forum.NET
This page was generated in 0.127 seconds.