Page 1 of 1

SQL help

Posted: Wed Jun 27, 2007 6:56 pm
by PaP

Code: Select all

SELECT DISTINCT rooms.id 
FROM rooms, contracts 
WHERE rooms.id != contracts.room_id 
AND '2007-06-29' <= contracts.end_date AND '2007-09-12' >= contracts.start_date

Code: Select all

SELECT DISTINCT rooms.id 
FROM rooms, contracts 
WHERE rooms.id = contracts.room_id 
AND '2007-06-29' <= contracts.end_date AND '2007-09-12' >= contracts.start_date
Δε ξέρω αν μπορεί να βοηθήσει κάποιος γιατί σπάω το κεφάλι μου χωρίς απότελεσμα εδώ και 5 ώρες περίπου. Εχω 2 πίνακες τους rooms και contracts... Ο δεύτερος περιέχει ένα πεδίο room_id το οποίο δειχνει στο rooms. To where clause δεν μας πολυ νοιάζει... Αλλά υποτίθεται ότι το rooms.id != contracts.room_id αποκλίει τις εγγραφές για τις οποίες ισχύει αυτο που είναι από τo ΑND και μετά, αλλά εμφανίζει τα πάντα... !!!
Και όταν βάζω rooms.id = contracts.room_id τότε απλά εμφανίζει αυτά που θέλω να αποκλείσω. Δοκίμασα και nested query

Code: Select all

SELECT DISTINCT room_id FROM rooms WHERE id NOT IN (SELECT room_id FROM contracts WHERE '2007-06-29' <= end_date AND '2007-09-12' >= start_date
Αλλά η χαζό mysql αρνείται να εκτελέσει queries μέσα σε παρένθεση !!

Posted: Wed Jun 27, 2007 8:19 pm
by Luke
Πάντως στο φωλιασμένο query, αν έχεις έκδοση mysql που υποστηρίζει τα φωλιασμένα queries, λείπει η τελευταία δεξιά παρένθεση και ίσως αυτό να δημιουργεί το πρόβλημα.

Posted: Wed Jun 27, 2007 9:33 pm
by PaP
απλά στο copy paste δεν υπάρχει... τέσπα το έλυσα με πολύ μπακαλίστικο τρόπο αν βρω στιγμή θα το κοιτάξω αλλά είναι πολύ περίεργο

Posted: Wed Jun 27, 2007 9:49 pm
by tsilochr
παίζεις με το EXIST που είναι και η πιο optimized λύση

Code: Select all

SELECT DISTINCT rooms.id
FROM rooms
WHERE ΝΟΤ EXISTS (SELECT 1 from  contracts where rooms.id = contracts .room_id)  AND ...
ανάλογα την έκδοση SQL ίσως θέλει alias στο select

Code: Select all

SELECT DISTINCT rooms.id as RID
FROM rooms
WHERE ΝΟΤ EXISTS (SELECT 1 from  contracts where RID = contracts .room_id ) AND ...
Δοκίμασε το και αν παίξει, plz πες το για να δω αν κατάλαβα σωστά. Επίσης παίξε με dateif και between

Posted: Wed Jun 27, 2007 9:50 pm
by PaP
σωστά το λες αλλά όταν βάλω ένα query σε παρένθεση δε το εκτελεί !! φταίει η έκδοση (5.0 αλλά και ο σερβερ ειναι 4.1 και πάλι σκ@@@@λες)

Posted: Fri Jun 29, 2007 9:56 pm
by vasvas
Λοιπόν, η επερώτησή σου προφανώς τα βγάζει όλα τα room.id, διότι σχεδόν κάθε συνδυασμός room.id και contract room.id περνάει το πρώτο τεστ, σωστά;

Πχ
room
1 blah
2 blah
3 foo


contracts
contract id room_id
1 1
2 2
3 2
4 1

Οταν κάνω το
FROM rooms, contracts
where room.id != contract.room_id

ποιές πλειάδες θα πάρω πίσω;

1 blah 2 2
1 blah 3 2
2 blah 1 1
2 blah 4 1
3 foo 1 1
3 foo 2 2
3 foo 3 2
3 foo 4 1

Όπως βλέπεις, η λίστα έχει όλα τα room.id. Δηλ. η επερώτηση δεν κάνει αυτό που θέλεις. Αν τη γράψεις σε σχεσιακή άλγεβρα μπορείς να αποδείξεις εύκολα ότι οι δυο SQL που δίνεις δεν είναι ισοδύναμες.

Το nested subquery σύμφωνα με το manual υποστηρίζεται
http://dev.mysql.com/doc/refman/5.0/en/subqueries.html

Εκτός από τις λύσεις με το nested subquery, μπορείς να χρησιμοποιήσεις τον τελεστή Difference , δηλ να αφαιρέσεις από το ROOMS αυτά που δε θες (που είναι στο nested subquery)
δηλ να γράψεις ROOMS DIFFERENCE (SELECT .... )
Ομως αυτό δεν το υποστηρίζει η ΜySQL. Τρίτη λύση: φτιάξε ένα stored procedure (που τα υποστηρίζει).