![]() |
Har en lurig MySQL-fråga jag inte får ordning på!
Jag har två tabeller som har samma två fält (ID och Value). Jag vill ta ut de rader ur tabell 1 vars ID finns någonstans i tabell 2 men där kombinationen av ID och Value inte finns. Tabell1: ID Value ----------------------- 1 Green 1 Red 1 Blue 2 Red 2 Green 2 Brown Tabell2: ID Value ---------------------- 1 Red 1 Green Jag vill alltså få ut enbart den tredje raden i tabell 1 eftersom "ID = 1" finns i tabell 2 men inte kombinationen "ID=1, Value=Blue". Eftersom ID=2 inte finns i tabell 2 så skall de raderna inte finnas i resultatet. Några förslag? |
SELECT * FROM Tabell1 t1 WHERE t1.ID IN (
SELECT t2.ID FROM Tabell2 t2 WHERE NOT t1.`value` = t2.`value` ) Kanske?! |
Nja, jag testade men då fick jag med rader som inte finns i tabell 2 (rad 5 och 6).
Kan man "joina" på två kolumner i MySQL, alltså två "ON"? |
Kod:
SELECT * FROM tabell1 where ID IN (SELECT ID FROM tabell2) AND Value NOT IN (SELECT Value FROM tabell2) |
chrizz:
Problemet är att samma värde kan förekomma för olika ID. Om vi lägger till raden "2 Blue" i båda tabellerna så kommer ju "1 Blue" inte hamna i resultatet, "SELECT Value FROM tabell2" kommer ju innehålla "Blue". Jag antar att man måste köra ngn slags JOIN så att ID och Value paras ihop rätt och sedan ta ut de rader där tabell 2 har NULL för Value... hmm... jag kanske har något där... |
Uuuusch vad detta blev fult, men det gör jobbet iaf. Nåt att snygga till : )
Kod:
select t1.id, t1.value |
Är det små eller stora tabeller? Är de större så är det nog bättre att göra en del av detta i php-koden istället.
|
Tabellerna är stooora... tyvärr.
Perben: Jag kom fram till något liknande, tyvärr så tar "NOT IN"-subqueryn alldeles för lång tid. |
prova DISTINCT?
|
TROR jag har det.
Med en UNION ALL på båda tabellerna och en koll av hur många gånger en rad förekommer (2 gånger så finns raden i båda tabellerna, 1 gång så finns den bara i tabell1). Kod:
Frågan är hur snabb denna fråga är när mängden data växer. Hur är prestandat på "UNION ALL" rent generellt, bevaras eventuella index? |
UNION gör en implicit DISTINCT, så den går långsammare än UNION ALL, som förutsätter att det du smäller samman är unikt (vet inte vad du har för PK eller unique constraints i dina tabeller).
Gräsligt query du skaffat dig i alla fall.. jag skulle råda till omdesign, men det kanske inte är aktuellt om tabellerna nu var så stora :) |
Jag tycker också det känns som att databasdesignen inte är helt optimal. Finns det ingen möjlighet till ombyggnad så kan du kanske ordna med någon cache-funktionalitet om det inte måste vara purfärska data?
|
Jag vet inte riktigt hur man skulle kunna göra designen bättre, vad det handlar om är att lagra i en tabell (tabell 2) vilka värden som är tillåtna för ett visst attribut i en annan (tabell 1). Frågan kommer inte köras så ofta och inte av användarna utan bara av "administratören".
@Perben: Vad menar du med att allt som man smäller samman ska vara unikt? |
Andi,
Det beror lite på vilken motor man använder på baksidan, men oftast är det så att UNION (vilket är ett alias för UNION DISTINCT på väldigt många databaser) skapar en slags temporär tabell för att kolla duplicerade entries. UNION ALLhar ingen sådan koll. Så om man vet att datat man sätter ihop med en union är unikt är UNION ALL snabbare. Det finns rätt väl beskrivet både för MS SQL och MySQL, vet att Oracle har samma "syndrom." http://www.mysqlperformanceblog.com/...l-performance/ http://blog.sqlauthority.com/2007/03...r-performance/ |
OK, jag fattar, tack!
Måste även tacka alla andra som kom med förslag på lösningar! |
Alla tider är GMT +2. Klockan är nu 00:20. |
Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson