i-orMedlem sedan nov. 2001294 inlägg Jag har en SQL-fråga som förenklad ser ut så här:
SQL = "SELECT name FROM tabell1, tabell2 WHERE tabell1.name = tabell2.name AND tabell2.koll = 1"
Nu är det så att alla namn i t1 inte finns i t2. Men jag vill fortfarande att de ska skrivas ut.
Alltså, de som inte finns i tabell2 ska skrivas ut samt de som finns i tabell2 och har "koll"-värdet 1. De som finns i tabell2 och inte har "koll"-värdet ska inte skrivas ut.
Hur ska SQL-satsen se ut?
SebbeMedlem sedan jan. 20032 285 inlägg strSQL = "SELECT tabell1.name, tabell2.name FROM tabell1 LEFT OUTER JOIN tabell2 ON tabell1.name = tabell2.name WHERE tabell2.koll = 1"
Kanske något sånt?
i-orMedlem sedan nov. 2001294 inlägg Tyvärr så funkade inte det.
Den ger fortfarande bara ut de namn som finns i båda tabellerna.
SebbeMedlem sedan jan. 20032 285 inlägg Kan det inte vara så att alla namn i tabell2 som har koll = 1 finns i tabell1 också?
i-orMedlem sedan nov. 2001294 inlägg Jo, alla namn i tabell2 finns i tabell1 men inte tvärtom.
@ndersMedlem sedan juni 200032 969 inlägg Om alla i tabell2 finns i tabell1, varför blandar du in tabell1 överhuvudtaget?
SELECT * FROM tabell2 WHERE koll='1'
red: eller är det så att detta inte är din egentliga sql-fråga?
LarsGMedlem sedan dec. 200012 464 inlägg strSQL = "SELECT tabell1.name, tabell2.name FROM tabell1 LEFT OUTER JOIN tabell2 ON (tabell1.name = tabell2.name and tabell2.koll = 1)"
i-orMedlem sedan nov. 2001294 inlägg Anders: Det stämmer, egentligen ska jag hämta ut en massa poster från tabell1 som inte är relaterade med tabell2.
LarsG: Det fungerade inte. SQL-satsen struntade i "tabell2.koll = 1"-kommandot.
LarsGMedlem sedan dec. 200012 464 inlägg Det verkar vara lite förbistring med avseende på vad du vill ha för resultat.
Visa lite exempeldata och vad du förväntar dig för resultat.
i-orMedlem sedan nov. 2001294 inlägg I tabell1 lagras besökarnas träningspass och i tabell2 lagras besökarnas inställningar.
Det jag ska försöka göra med SQL-satsen är att lista de besökare som har lagt till träningspass den senaste veckan såvida de inte har valt i inställningarna att inte ha en offentlig träningsdagbok.
Exempel:
Tabell1:
Olle - 2003-03-19 - Löpning
Kalle - 2003-03-17 - Simning
Ulla - 2003-03-18 - Cykling
Kalle - 2003-03-17 - Löpning
Tabell2:
Ulla - inte offentlig
Kalle - offentlig
Listan över de som lagt till träningspass senaste veckan:
Olle (han har inte angett några inställningar och ska visas)
Kalle (han vill vara offentlig och ska visas)
Ulla ska inte visas.
SebbeMedlem sedan jan. 20032 285 inlägg strSQL = "SELECT tabell1.namn, tabell2.namn FROM tabell1 LEFT OUTER JOIN tabell2 ON tabell1.namn = tabell2.namn WHERE tabell2.koll NOT IN ('0')"
Kanske funkar? Problemet är (tycker jag) att kollen ligger i tabell2.
i-orMedlem sedan nov. 2001294 inlägg Tyvärr fungerade inte det heller.
Det känns väldigt dåligt att köra en SQL-sats för varje post i tabell1, men jag kanske är tvungen.
aasahMedlem sedan mars 20034 471 inlägg Nu är jag säkert ute och cyklar men borde det inte vara så här:
SELECT tabell1.namn FROM tabell1, tabell2 WHERE
tabell1.namn = tabell2.namn AND tabell2.koll='1';
union
(SELECT namn FROM tabell1
difference
SELECT namn FROM tabell2);
Det borde funka... men kan förmodligen skrivas bättre.
i-orMedlem sedan nov. 2001294 inlägg Union? Difference?
Vad gör dem? Eftersom jag inte vet vad de gör var jag tvungen att skriv din SQL-sats ordagrant och då blev det fel. Jag antar att jag ska ändra någonting, typ att skriva ut någonting istället för "difference".
aasahMedlem sedan mars 20034 471 inlägg Mitt fel! Byt difference mot except så funkar det nog.
(difference är ett annat språk än SQL och jag brukar vara bra på att blanda ihop uttrycken, förlåt! :r )
Om du använder SQL92 eller senare ska mängdoperatorer finnas med. De gör helt enkelt samma sak som de matematiska operatorerna U respektive \.
Exempel:
S = {Personer i 7A}
T = {Pojkarna i skolan}
S U T = Mängden av alla pojkar i skolan och dessutom alla flickor i 7A, dvs allting ur båda mängderna.
S \ T = Mängden av flickor i 7A, dvs allting ur S som inte finns i T.
i-orMedlem sedan nov. 2001294 inlägg Det blev riktigt komplicerat det här.
Så här ser SQL-satsen ut i sin helhet:
SQL = "SELECT Max(t_diaryworkouts.f_date) AS f_date, t_diaryworkouts.f_runner, t_members.f_username FROM t_diaryworkouts, t_diarysettings, t_members WHERE t_members.f_id = t_diaryworkouts.f_runner AND t_diaryworkouts.f_runner = t_diarysettings.f_runner AND CURRENT_DATE - f_date < 7 AND t_diarysettings.f_who <> 1 GROUP BY t_diaryworkouts.f_runner, t_members.f_username ORDER BY f_date DESC, t_members.f_username"
Nu visas inte de löpare som inte finns i t_diarysettings.
Om jag lägger till:
UNION (SELECT f_runner FROM t_diaryworkouts EXCEPT SELECT f_runner FROM t_diarysettings)
Får jag detta felmeddelande:
[TCX][MyODBC]You have an error in your SQL syntax near 'UNION (SELECT f_runner FROM t_diaryworkouts EXCEPT SELECT f_runner FROM t_diarys' at line 1
Vad är felet?
aasahMedlem sedan mars 20034 471 inlägg Problemet är att kolumnerna inte matchar. I mitt exempel, fast rättat, har vi:
SELECT tabell1.namn FROM tabell1, tabell2 WHERE
tabell1.namn = tabell2.namn AND tabell2.koll='1';
union
(SELECT namn FROM tabell1
except
SELECT namn FROM tabell2);
Dvs varje Select statement har lika många kolumner och av samma typ. Detta är oerhört viktigt.
Vänta ett tag!! Du vill ha ut alla namn ur tabell1 som inte uttryckligen har sagt annat i tabell2. De som har sagt annat har koll = 0 i tabell2? Då kan det skrivas enklare!
SELECT namn FROM tabell1
except
SELECT namn FROM tabell2
where koll = 0;
I din fullständiga fråga måste du ha ovanstående som ett inre uttryck för att få kolumnerna att stämma. Så se till att ha:
SELECT Max(..) ... FROM ....
WHERE ... and t_diaryworkouts.f_runner in
( SELECT namn FROM tabell1
except
SELECT namn FROM tabell2
where koll = 0);
aasahMedlem sedan mars 20034 471 inlägg Det här kom till av misstag: Jag tryckte citera i stället för redigera på mitt eget inlägg. Snälla ta bort! Och jag ber om ursäkt, det var inte meningen :r
i-orMedlem sedan nov. 2001294 inlägg Jag vet inte varför jag inte slutförde lösandet av ovanstående problem förra året. Men faktum är att det problemet kvarstår.
Jag försökte fixa problem med hjälp av aasahs exempel, men jag måste ha skrivit någonting fel.
SQL = "SELECT Max(t_diaryworkouts.f_date) AS f_date, t_diaryworkouts.f_runner, t_members.f_username FROM t_diaryworkouts, t_members WHERE t_members.f_id = t_diaryworkouts.f_runner AND f_date between adddate(current_date, interval -7 day) and current_date AND t_diaryworkouts.f_runner IN (SELECT f_runner FROM t_diaryworkouts EXCEPT SELECT f_runner FROM t_diarysettings WHERE f_who = 1) GROUP BY t_diaryworkouts.f_runner, t_members.f_username ORDER BY f_date DESC, t_members.f_username"
Vad är fel i SQL-satsen?
Det vore jätteschysst om någon kunde sätta sig in i problematiken och göra ett nytt försök.
LarsGMedlem sedan dec. 200012 464 inlägg Det är inte fel i SQL satsen. Felet finns i Mysql som varken har stöd för except eller subselect. Jag återkommer.