Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

SQL Επερώτηση - Επιλογή όλων των πεδίων ενός πίνακα όπου ένα χαρακτηριστικό είναι μέγιστο

Îåêßíçóå áðü ôï ìÝëïò Paul. Τελευταία δημοσίευση από το μέλος Παναγιώτης Καναβός στις 04-08-2006, 23:48. Υπάρχουν 9 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  03-08-2006, 05:31 15427

    Time [O] SQL Επερώτηση - Επιλογή όλων των πεδίων ενός πίνακα όπου ένα χαρακτηριστικό είναι μέγιστο

    Καλημέρα,

    Προσπαθώ να εκτελέσω την εξής επερώτηση:

    select * from table where id = MAX(id) , αλλά εμφανίζεται μήνυμα λάθους. Μπορεί να με βοηθήσει κάποιος; Θέλω να επιλέξω όλα τα στοιχεία της γραμμής του πίνακα, η οποία έχει το μέγιστο id. (το id είναι πεδίο του πίνακα)

     

    Ευχαριστώ πολύ!

     

  •  03-08-2006, 09:07 15429 σε απάντηση της 15427

    Απ: SQL Επερώτηση - Επιλογή όλων των πεδίων ενός πίνακα όπου ένα χαρακτηριστικό είναι μέγιστο

    Μία λύση είναι να χρησιμοποιήσεις subquery:

    SELECT *
    FROM table
    WHERE id = (SELECT max(id) FROM table)

    Ουσιαστικά, το MAX ως ένα από τα aggregate functions, δεν μπορεί να χρησιμοποιηθεί όπως προσπαθούσες να το χρησιμοποιήσεις γιατί χρειάζεται ένα set από τιμές για να βρει την μέγιστη. Άρα θα πρέπει να βρίσκεται μαζί με ένα SELECT που θα "τραβήξει" τη λίστα με τις τιμές.


    Vir prudens non contra ventum mingit
  •  03-08-2006, 21:46 15461 σε απάντηση της 15427

    Απ: SQL Επερώτηση - Επιλογή όλων των πεδίων ενός πίνακα όπου ένα χαρακτηριστικό είναι μέγιστο

    Ευχαριστώ πολύ για την πολύ κατατοπιστική απάντηση!
  •  03-08-2006, 21:49 15462 σε απάντηση της 15461

    Απ: SQL Επερώτηση - Επιλογή όλων των πεδίων ενός πίνακα όπου ένα χαρακτηριστικό είναι μέγιστο

    Μην ξεχνάς να ενημερώνεις το status της ερώτησης...
    Vir prudens non contra ventum mingit
  •  04-08-2006, 14:45 15494 σε απάντηση της 15427

    Απ: SQL Επερώτηση - Επιλογή όλων των πεδίων ενός πίνακα όπου ένα χαρακτηριστικό είναι μέγιστο

    για MS SQL :

    SELECT TOP 1 *

    FROM table

    ORDER BY id DESC

    --HTH--
  •  04-08-2006, 15:47 15500 σε απάντηση της 15494

    Απ: SQL Επερώτηση - Επιλογή όλων των πεδίων ενός πίνακα όπου ένα χαρακτηριστικό είναι μέγιστο

     spaceman wrote:
    για MS SQL :

    SELECT TOP 1 *

    FROM table

    ORDER BY id DESC

    --HTH--


    Αυτό είναι σωστό αν το πεδίο ID είναι μοναδικό (από το όνομά του αυτό υποθέτουμε). Σε πεδία που δεν είναι μοναδικά, η λύση είναι μόνο αυτή που έχει δοθεί σε προηγούμενα posts.

    Νατάσα Μανουσοπούλου
  •  04-08-2006, 16:00 15504 σε απάντηση της 15494

    Απ: SQL Επερώτηση - Επιλογή όλων των πεδίων ενός πίνακα όπου ένα χαρακτηριστικό είναι μέγιστο

    Μόλις διαπίστωσα και ένα περίεργο: Ο SQL Server θα δημιουργήσει ακριβώς το ίδιο execution plan και στις δύο περιπτώσεις (αν υπάρχει index φυσικά)! Από πλευράς ταχύτητας και οι δύο λύσεις είναι ίδιες!

    Από πλευράς ευελιξίας όμως, η πρώτη λύση είναι καλύτερη, καθώς δουλεύει και όταν το πεδίο δεν είναι μοναδικό, καθώς και με διαφορετικές στατιστικές συναρτήσεις.
    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  04-08-2006, 20:07 15510 σε απάντηση της 15504

    Απ: SQL Επερώτηση - Επιλογή όλων των πεδίων ενός πίνακα όπου ένα χαρακτηριστικό είναι μέγιστο

    Απο προσωπικη εμπειρια, εχει διαπιστωθει οτι το ΜΑΧ() ειναι ιδιαιτερα χρονοβορο οταν εφαρμοζεται σε πινακα με πολλες εγγραφες.

    Επειδη δεν υπαρχει δυνατοτητα προσβασης σε SQL server, αν υπαρχει διαθεση απο καποιον χρηστη να ασχοληθεί, θα μπορουσε να δημιουργηθει ενας πινακας, (με ή χωρις index), να προστεθουν "αρκετες εγγραφες" και μετα να εκτελεστουν οι δυο διαφορετικες εκδοχες.

    --test table creation

    CREATE TABLE mytest(id INT)

    --create driving records

    DECLARE @i INT

    SET @i = 1

    WHILE @i <= 300000

    BEGIN

    INSERT INTO mytest(id) VALUES(@i)

    --move to next @i

    SET @i = @i+1

    END

    DECLARE @thedate DATETIME

    --plan No:1

    SET @thedate = getdate()

    SELECT *

    FROM mytest

    WHERE id = (SELECT max(id) FROM mytest)

    --show milliseconds of execution

    SELECT DATEDIFF(ms, @thedate, getdate()) AS 1st_plan

    --plan No:2

    SET @thedate = getdate()

    SELECT TOP 1 *

    FROM mytest

    ORDER BY id DESC

    SELECT DATEDIFF(ms, @thedate, getdate()) AS 2nd_plan

    DROP TABLE mytest

    ------------------------------------------------------------------------------------------

    Αν μπορεσει καποιος χρηστης, να δημοσιευσει τους δυο χρονους..ή να εκτελεσει τα select queries χωριστα και να παρουσιασει τα αποτελεσματα της εκτελεσης...

  •  04-08-2006, 20:41 15512 σε απάντηση της 15510

    Απ: SQL Επερώτηση - Επιλογή όλων των πεδίων ενός πίνακα όπου ένα χαρακτηριστικό είναι μέγιστο

    Πέρα από αυτό που επεσήμανε η mns σχετικά με το τι ακριβώς θέλουμε να κάνουμε, το performance αλλάζει δραματικά ανάλογα αν υπάρχει index ή όχι. Αν υπάρχει clustered index, τα δεδομένα είναι ήδη ταξινομημένα και γι αυτόν το λόγο τόσο το ORDER BY, όσο και το MAX δημιουργούν τελικά το ίδιο execution plan όπως είπε ο Παναγιώτης και εκτελούνται πρακτικά στον ίδιο χρόνο (με το MAX να είναι 16 ms ταχύτερο). Όταν δεν υπάρχει index, τότε η λύση με το MAX απαιτεί να γίνουν δύο περάσματα (table scans) το πρώτο για να βρεθεί το MAX και το δεύτερο, εκ νέου, για να βρεθούν όλες οι εγγραφές που έχουν τιμή στο πεδίο αναζήτησης, ίδια με το MAX.

    Για να το διαπιστώσεις, δοκίμασε ότνα βρεις ευκαιρία να ξανατρέξεις το script βάζοντας μετά το CREATE TABLE το

    CREATE CLUSTERD INDEX CL_mytest ON mytest(id)

    Τουτέστιν, δεν είναι το MAX χρονοβόρο, είναι η σωστή ή η λανθασμένη υλοποίηση των indexes που κάνει τη διαφορά...


    Vir prudens non contra ventum mingit
  •  04-08-2006, 23:48 15514 σε απάντηση της 15512

    Απ: SQL Επερώτηση - Επιλογή όλων των πεδίων ενός πίνακα όπου ένα χαρακτηριστικό είναι μέγιστο

    Ο Kelman έχει δίκιο. Δεν ανέφερα θεωρητικά ότι και οι δύο λύσεις έχουν την ίδια απόδοση. Τις εφάρμοσα και τις δύο σε ένα πίνακα με primary key το ID και διαπίστωσα με έκπληξη ότι και στις δύο περιπτώσεις ο SQL Server εκτελούσε το ίδιο execution plan: Ένα index scan ακολουθούμενο από ένα TOP. Αυτό συμβαίνει επειδή ο SQL Server ξέρει ότι το primary key έχει index, οπότε το μόνο που χρειάζεται να κάνει είναι να διαβάσει όλες τις τιμές του index με τη σειρά, και να επιλέξει την πρώτη.

    Πάντως, το παραπάνω script δεν είναι κατάλληλο για benchmarks επειδή τα δεδομένα του πίνακα έχουν ήδη φορτωθεί στη μνήμη όταν τρέχει το δεύτερο select.

    Ο μόνος τρόπος να πάει πιο γρήγορα αυτό το query είναι να υπάρχει άλλο ένα index στο ID, με descending sort order. Και σε αυτή την περίπτωση όμως, τα execution plans είναι τα ίδια. Η λύση αυτή πάντως ακούγεται υπερβολική.
    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems