|
Îåêßíçóå áðü ôï ìÝëïò cap. Τελευταία δημοσίευση από το μέλος cap στις 28-04-2005, 15:36. Υπάρχουν 20 απαντήσεις.
-
14-04-2005, 14:44
|
-
cap
-
-

-
Μέλος από τις 14-01-2005
-
Βύρωνας, Αθήνα
-
Δημοσιεύσεις 2.750
-
-
|
Μερικά σύνολα (count) τιμών πεδίων πίνακα υπό συνθήκη
Εχω ένα πίνακα ο οποίος είναι (υποθετικά) κάπως έτσι: ID | Status | 1 | A | 2 | A | 3 | C | 4 | B | κλπ. (με επιπρόσθετες ίσως κολώνες) Θέλω να πάρω μερικά σύνολα για το status σε κάθε περίπτωση καθώς και τα συνολικά τους. Κάνω το εξής: select distinct (cus.id) , sum(case cus.status when 'A' then 1 else 0 end) as status1count , sum(case cus.status when 'B' then 1 else 0 end) as status2count , sum(case cus.status when 'C' then 1 else 0 end) as status3count , count(cus.status) as fullcount from customers cus group by cus.id Εχει δοκιμάσει κανείς κανέναν άλλον, πιό αποτελεσματικό τρόπο; Φανταστείτε οτι αυτό το μαραφέτι θα γίνεται join μετά με χιλια δυο αλλα πράγματα. Επίσης σίγουρα θα υπαρχει και where clause. Δεν ψαχνω για σωστό / λάθος, απλά θέλω να δω μήπως υπάρχει κανένας άλλος τρόπος που δεν έχω σκεφτεί.
Σωτήρης Φιλιππίδης DotSee Web Services
|
|
-
14-04-2005, 15:13
|
|
Re: Μερικά σύνολα (count) τιμών πεδίων πίνακα υπό συνθήκη
Μάλλον θα πρέπει να δώσεις άλλο παράδειγμα. Αν ήθελες απλώς τα μερικά αθροίσματα ανά status και το συνολικό θα μπορούσες να γράψεις: select status,count(*) from customers group by status with rollup και να πάρεις status ------ ----------- A 2 B 1 C 1 NULL 4 Μήπως αυτό που ζητάς είναι για κάθε customer το άθροισμα ανά status και το συνολικό του?
Παναγιώτης Καναβός, Freelancer Twitter: http://www.twitter.com/pkanavos
|
|
-
-
25-04-2005, 22:19
|
-
isidoros
-
-
-
Μέλος από τις 02-10-2004
-
Ηλιούπολη
-
Δημοσιεύσεις 32
-
-
|
Re: Μερικά σύνολα (count) τιμών πεδίων πίνακα υπό συνθήκη
"με την μία" δεν γίνετε ... εκτός και αν καλείς και μια π.χ. function
δηλαδή
select status,count(id),dbo.gettotalstatus(customerid) from ΧΧΧΧ
group by status,customerid having customerid = ΝΝΝ
και όπου gettotalstatus
CREATE FUNCTION GetTotalStatus
(@id int)
RETURNS int
AS
begin
Declare @nTotal int
set @nTotal = (select count(id) from xxxx where customerid = @id)
return @nTotal
END
Seretis Isidoros ---------------------- Join the army Travel the world, Meet interesting people And kill them.
|
|
-
26-04-2005, 09:03
|
-
cap
-
-

-
Μέλος από τις 14-01-2005
-
Βύρωνας, Αθήνα
-
Δημοσιεύσεις 2.750
-
-
|
Re: Μερικά σύνολα (count) τιμών πεδίων πίνακα υπό συνθήκη
Σωστά, Ισίδωρε. Ειναι και αυτή μια λύση, με τη διαφορά οτι έτσι θα φέρω αποτελέσματα για συγκεκριμένο id. Βεβαια, μπορεί κανείς να το κάνει πιό γενικό. Το θέμα είναι οτι οι άτιμες οι UDF είναι πολύυυυ αργές. Μια που το λέμε, ένα πράγμα που δεν ήξερα και ανακάλυψα τώρα τελευταία είναι το εξής: Αν βάλεις UDF στο WHERE clause σου και κάνεις π.χ ένα SELECT something FROM sometable WHERE myUDF(blabla)=kati αν ο πίνακας έχει 10000 rows και εσύ αναμένεις να γυρίσουν 5, παρ'όλα αυτά η UDF έχει γίνει evaluate 10000 φορές! :( Παντως να επισημάνω οτι ο πρώτος τρόπος που ανέφερα (στην αρχή του post) παίζει. Απλά ήθελα να δω εναλλακτικές που δεν είχα σκεφτεί, και αυτή που προτείνεις είναι όντως μια εναλλακτική λύση.
Σωτήρης Φιλιππίδης DotSee Web Services
|
|
-
26-04-2005, 10:08
|
|
Re: Μερικά σύνολα (count) τιμών πεδίων πίνακα υπό συνθήκη
Σωστά, γιατί ο SQL Server πρέπει να συγκρίνει το αποτέλεσμα του UDF με το kati. Γι αυτό καλό είναι να βρεις ένα τρόπο να γράψεις αντί για:
WHERE myUDF(pedio)= kati
το
WHERE pedio=myInverseUDF(kati)
Παναγιώτης Καναβός, Freelancer Twitter: http://www.twitter.com/pkanavos
|
|
-
-
27-04-2005, 18:52
|
|
Re: Μερικά σύνολα (count) τιμών πεδίων πίνακα υπό συνθήκη
Μήπως να έφτιαχνες ένα view με τα γενικά σύνολα και να το έκανες join με τα groupαρισμένα ?
SELECT Table1.CustomerID, Table1.Status, COUNT(Table1.id) AS GroupCount, VIEW1.[Count] FROM Table1 INNER JOIN VIEW1 ON Table1.CustomerID = VIEW1.CustomerID GROUP BY Table1.CustomerID, Table1.Status, VIEW1.[Count] ORDER BY Table1.CustomerID, Table1.Status
με το view:
SELECT CustomerID, COUNT(id) AS [Count] FROM dbo.Table1 GROUP BY CustomerID
Βέβαια θα σε πηδάει στο performance...
Χρήστος Γεωργακόπουλος
|
|
-
28-04-2005, 11:03
|
-
cap
-
-

-
Μέλος από τις 14-01-2005
-
Βύρωνας, Αθήνα
-
Δημοσιεύσεις 2.750
-
-
|
Re: Μερικά σύνολα (count) τιμών πεδίων πίνακα υπό συνθήκη
Δεν ειν'κακό.... Αν και όντως από performance είναι άστα να πανε. Οκ, πιστεύω οτι έχω μια εναλλακτική.
Σωτήρης Φιλιππίδης DotSee Web Services
|
|
-
28-04-2005, 11:26
|
-
KelMan
-
-
-
Μέλος από τις 03-11-2004
-
Planet Earth
-
Δημοσιεύσεις 2.851
-
-
|
Re: Μερικά σύνολα (count) τιμών πεδίων πίνακα υπό συνθήκη
Για τη δεύτερη λύση δεν είναι ανάγκη να φτιάξεις view ίσα-ίσα για να εξυπηρετήσεις το query σου. Μπορείς να κάνεις join τον πίνακα με τον εαυτό του, ως δεύτερο instance του πίνακα. Αυτή είναι και η συνηθισμένη λύση για περίεργα quieries με groupαρίσματα (την προτείνει και ο Itzik-Ben Gan του SQL Server Magazine). Μου κάνει εντύπωση που λέτε ότι από performance είναι άστα να πάνε, ιδιαίτερα σε σχέση με τη λύση του CASE (ο γενικός κανόνας είναι να μην χρησιμοποιείται η procedural λογική του case σε σχέση με τη SET λογική του select). Όχι ότι είμαι άπιστος Μάνος αλλά τι λέει το execution plan σε κάθε περίπτωση;
Vir prudens non contra ventum mingit
|
|
-
28-04-2005, 11:53
|
-
cap
-
-

-
Μέλος από τις 14-01-2005
-
Βύρωνας, Αθήνα
-
Δημοσιεύσεις 2.750
-
-
|
Re: Μερικά σύνολα (count) τιμών πεδίων πίνακα υπό συνθήκη
Δοκιμάζοντας και τα δύο (τη δική μου πρώτη λύση και τη λύση του cgeo αλλά με join του πινακα στον εαυτό του), βλέπω τα εξής:
(Πινακας με 35000 εγγραφές περίπου, 3 statuses (P, C, A) )
select distinct (cus.userid) , sum(case cus.status when 'P' then 1 else 0 end) as status1count , sum(case cus.status when 'C' then 1 else 0 end) as status2count , sum(case cus.status when 'A' then 1 else 0 end) as status3count , count(cus.status) as fullcount from myTable cus group by cus.userid (1 row(s) affected) |--Compute Scalar(DEFINE:([Expr1004]=Convert([Expr1010]))) |--Hash Match(Aggregate, HASH:([cus].[USERID]), RESIDUAL:([cus].[USERID]=[cus].[USERID]) DEFINE:([Expr1001]=SUM(If ([cus].[STATUS]='P') then 1 else 0), [Expr1002]=SUM(If ([cus].[STATUS]='C') then 1 else 0), [Expr1003]=SUM(If ([cus].[STATUS]='A') then 1 else 0), [Expr1010]=COUNT(*))) |--Clustered Index Scan(OBJECT:([MYDATABASE].[dbo].[MYTABLE].[MYTABLE_PK] AS [cus])) Δεύτερη περίπτωση:
SELECT cus.userid , cus.status , COUNT(cus.userid) AS GroupCount , cuscopy.cnt FROM myTable as cus INNER JOIN ( SELECT cus1.userid , count (cus1.userid) as cnt FROM myTable cus1 GROUP BY cus1.userid) AS cuscopy ON cus.userid= cuscopy.userid GROUP BY cus.userid, cus.status, cuscopy.cnt ORDER BY cus.userid, cus.status (1 row(s) affected) |--Sort(ORDER BY:([cus1].[USERID] ASC, [cus].[STATUS] ASC)) |--Hash Match(Inner Join, HASH:([cus1].[USERID])=([cus].[USERID]), RESIDUAL:([cus1].[USERID]=[cus].[USERID])) |--Compute Scalar(DEFINE:([Expr1001]=Convert([Expr1009]))) | |--Hash Match(Aggregate, HASH:([cus1].[USERID]), RESIDUAL:([cus1].[USERID]=[cus1].[USERID]) DEFINE:([Expr1009]=COUNT_BIG([cus1].[USERID]))) | |--Clustered Index Scan(OBJECT:([MYDATABASE].[dbo].[MYTABLE].[MYTABLE_PK] AS [cus1])) |--Compute Scalar(DEFINE:([Expr1003]=Convert([Expr1010]))) |--Hash Match(Aggregate, HASH:([cus].[USERID], [cus].[STATUS]), RESIDUAL:([cus].[USERID]=[cus].[USERID] AND [cus].[STATUS]=[cus].[STATUS]) DEFINE:([Expr1010]=COUNT(*))) |--Clustered Index Scan(OBJECT:([MYDATABASE].[dbo].[MYTABLE].[MYTABLE_PK] AS [cus])) Πράγμα που με κάνει γενικά να πιστεύω οτι τα CASE statements λειτουργούν πολύ καλύτερα από τα inner joins σε αυτή την περίπτωση.
Σωτήρης Φιλιππίδης DotSee Web Services
|
|
-
28-04-2005, 12:08
|
-
KelMan
-
-
-
Μέλος από τις 03-11-2004
-
Planet Earth
-
Δημοσιεύσεις 2.851
-
-
|
Re: Μερικά σύνολα (count) τιμών πεδίων πίνακα υπό συνθήκη
Έλπιζα ότι θα έκανες ένα screen capture για να δούμε το execution plan... Μου είναι εξαιρετικά δύσκολο να καταλάβω από το κείμενο (δεν είμαι Oracleάς τι να κάνουμε ). Δεδομένου ότι τα indexes είναι τα κατάλληλα, πόσα IO ops έχει το ένα και πόσα το άλλο;
Vir prudens non contra ventum mingit
|
|
-
-
28-04-2005, 12:29
|
-
KelMan
-
-
-
Μέλος από τις 03-11-2004
-
Planet Earth
-
Δημοσιεύσεις 2.851
-
-
|
Re: Μερικά σύνολα (count) τιμών πεδίων πίνακα υπό συνθήκη
Αν τις βάλεις ως συνημμένα?
Vir prudens non contra ventum mingit
|
|
-
28-04-2005, 12:30
|
Σελίδα 1 από 2 (21 εγγραφές)
1
|
|
|