Avatar billede slapstick Nybegynder
20. september 2005 - 11:46 Der er 9 kommentarer og
2 løsninger

brug for hjælp til outer join

jeg har et program der henter tekst osv til menuer fra min mysql db
i db er der en tabel der hedder services som indeholder default tekster og så har jeg en ekstra tabel der hedder service_language hvor jeg har tilføjet de ekstra sprog
men da det ikke er alle tekster der er oversat så skal den defaulte til teksterne i services tabellen hvis der ikke er en passende entry i service_language tabellen
det har jeg prøvet at gøre med left outer join..

hvis default sprog er valgt bruger den denne sql query og får 93 rows

SELECT services.serviceid, services.servicetype, services.servicesubtype, services.displayname, services.serviceurl, services.abouturl, services.dataurl, services.globalid, services.service_modified, services.about_modified, services.data_modified, services.countries, services.countryname, services.provider, services.providername, services.district, services.brickprocessing,services.seq_no, userpackages.packageusage, MAX(userpackages.expiredate) AS expiredate FROM userpackages INNER JOIN packageservices ON packageservices.packageid=userpackages.packageid INNER JOIN services ON services.serviceid=packageservices.serviceid WHERE userpackages.brugerid = 430 AND userpackages.expiredate >= 20050920 AND userpackages.activated= 'yes' GROUP BY services.serviceid, services.servicetype, services.displayname, userpackages.packageusage ORDER BY services.displayname,services.countryname,services.providername, services.seq_no, services.displayname+services.countryname ASC

og hvis et andet sprog er valgt bruger den denne sql query med left outer join og får kun 51 rows tilbage

SELECT services.serviceid, services.servicetype, services.servicesubtype, services.displayname AS defdisplayname ,services.serviceurl, services.abouturl, services.dataurl, services.globalid, services.service_modified, services.about_modified, services.data_modified, services.countries, services.countryname AS defcountryname, services.provider, services.providername, services.district, services.brickprocessing, services.seq_no, userpackages.packageusage, MAX(userpackages.expiredate) AS expiredate, service_language.displayname, service_language.countryname, service_language.lang FROM userpackages INNER JOIN packageservices ON packageservices.packageid=userpackages.packageid INNER JOIN services ON services.serviceid=packageservices.serviceid LEFT OUTER JOIN service_language ON service_language.serviceid = services.serviceid WHERE userpackages.brugerid = '430' AND ( service_language.lang = 'NO' OR service_language.lang IS NULL ) AND userpackages.expiredate >= 20050920 AND userpackages.activated= 'yes' GROUP BY services.serviceid, services.servicetype, services.displayname, userpackages.packageusage ORDER BY service_language.displayname,services.displayname,service_language.countryname,services.countryname,services.providername, services.seq_no, service_language.displayname+service_language.countryname ASC

det er jo mildest talt uhensigtmæssigt at den ikke får 93 rows i begge tilfælde hehe

nogen der kan gi en hånd?
Avatar billede ldanielsen Nybegynder
20. september 2005 - 12:14 #1
Så vidt jeg kan se laver du et outer join til service_language, hvilket skulle gøre at der kommer en post ud selvom der ikke findes én der matcher i service_language

Nu har jeg ikke så meget forstand på mysql, men i MSSQL kan du ikke select et felt i en grouped query hvis feltet ikke er enten med i Group by eller selectes med en aggregete function som Max, Min eller Avg. Alligevel selecter du

service_language.displayname,
service_language.countryname
og service_language.lang

- uden at de et grouped, det ville give en fejl i MSSQL. For eksperimentets skyld, så prøv at selecte Max() for dem alle:

... MAX(service_language.displayname) AS max_displayname,
MAX(service_language.countryname) AS max_countryname,
MAX(service_language.lang) AS max_lang ...
Avatar billede slapstick Nybegynder
20. september 2005 - 12:30 #2
den kommer ikke med fejl
og lister tomme felter for de rækker hvor de 3 felter ikek er udfyldt
Avatar billede ldanielsen Nybegynder
20. september 2005 - 12:42 #3
Men hvis du droppede at joine med service_language, ville den så komme med alle 93 poster?

Mener du at den kun returnerer 51 poster, eller mener du at der er 42 poster af det 93 hvor felterne er tomme?

Hvis det sidste er tilfældet så kan du bruge IFNULL:

IFNULL(service_language.displayname, services.displayname) AS displayname,
IFNULL(service_language.countryname, services.countryname) AS countryname,
IFNULL(service_language.lang, 'dansk') AS lang, ...
Avatar billede slapstick Nybegynder
20. september 2005 - 12:54 #4
ja hvis jeg bare bruger den første sql query jeg skrev hvor jeg ikke joiner med service_language så kommer den med 93
og ellers kommer den med 51 og nej det er ikke med 42 tomme rækker det er simpelthen kun de 51 hehe

med IFNULL der fylder den de tomme felter ud men viser stadig kun de 51 rækker
Avatar billede slapstick Nybegynder
20. september 2005 - 12:55 #5
her er den sql jeg prøvede:

SELECT services.serviceid, services.servicetype, services.servicesubtype, services.serviceurl, services.abouturl, services.dataurl, services.globalid, services.service_modified, services.about_modified, services.data_modified, services.countries, services.provider, services.providername, services.district, services.brickprocessing, services.seq_no, userpackages.packageusage, MAX(userpackages.expiredate) AS expiredate,
IFNULL(service_language.displayname, services.displayname) AS displayname, IFNULL(service_language.countryname, services.countryname) AS countryname, IFNULL(service_language.lang, 'DA') AS lang FROM userpackages INNER JOIN packageservices ON packageservices.packageid=userpackages.packageid INNER JOIN services ON services.serviceid=packageservices.serviceid LEFT OUTER JOIN service_language ON service_language.serviceid = services.serviceid WHERE userpackages.brugerid = '430' AND ( service_language.lang = 'NO' OR service_language.lang IS NULL ) AND userpackages.expiredate >= 20050920 AND userpackages.activated= 'yes' GROUP BY services.serviceid, services.servicetype, services.servicesubtype, displayname ,services.serviceurl, services.abouturl, services.dataurl, services.globalid, services.service_modified, services.about_modified, services.data_modified, services.countries, countryname, services.provider, services.providername, services.district, services.brickprocessing, services.seq_no, userpackages.packageusage, service_language.displayname, service_language.countryname, service_language.lang ORDER BY service_language.displayname,services.displayname,service_language.countryname,services.countryname,services.providername, services.seq_no, service_language.displayname+service_language.countryname ASC
Avatar billede ldanielsen Nybegynder
20. september 2005 - 13:05 #6
Hvad så hvis du bruger MAX også :

IFNULL(MAX(service_language.displayname), services.displayname) AS displayname, ..

osv.

- og er du sikker på at du behøver at GROUP'e?
Avatar billede slapstick Nybegynder
20. september 2005 - 13:57 #7
den her virker til gengæld !

SELECT services.serviceid, services.servicetype, services.servicesubtype, services.serviceurl,

services.abouturl, services.dataurl, services.globalid, services.service_modified, services.about_modified, services.data_modified, services.countries, services.provider, services.providername, services.district, services.brickprocessing, services.seq_no, userpackages.packageusage, MAX(userpackages.expiredate) AS expiredate,

IFNULL(service_language.displayname, services.displayname) AS displayname, IFNULL(service_language.countryname, services.countryname) AS countryname, IFNULL(service_language.lang, 'DA') AS lang FROM userpackages INNER JOIN packageservices ON packageservices.packageid=userpackages.packageid INNER JOIN services ON services.serviceid=packageservices.serviceid

LEFT OUTER JOIN service_language ON service_language.serviceid = services.serviceid AND service_language.lang = 'NB'

WHERE userpackages.brugerid = '430'

AND userpackages.expiredate >= 20050920 AND userpackages.activated= 'yes'

GROUP BY services.serviceid, services.servicetype, services.servicesubtype, displayname ,services.serviceurl, services.abouturl, services.dataurl, services.globalid, services.service_modified, services.about_modified, services.data_modified, services.countries, countryname, services.provider, services.providername, services.district, services.brickprocessing, services.seq_no, userpackages.packageusage, service_language.displayname, service_language.countryname, service_language.lang ORDER BY service_language.displayname,services.displayname,service_language.countryname,services.countryname,services.providername, services.seq_no, service_language.displayname+service_language.countryname ASC
Avatar billede ldanielsen Nybegynder
20. september 2005 - 14:20 #8
OK, så du group'er simpelthen dem alle, det burde jeg jo have foreslået.

Jeg blev jo nok forvirret over at der ikke kom nogen fejl.

Men godt at du fik det lavet
Avatar billede slapstick Nybegynder
20. september 2005 - 14:24 #9
ja det viste sig at rækkefølgen af joins og where betingelser havde en del at sige
tak for det nifty IFNULL sjov.. var en del mere elegant end at dobbelt selecte felter hehe
smid et svar så får du nogle point som tak for hjælpen !! :))))
Avatar billede ldanielsen Nybegynder
20. september 2005 - 14:29 #10
Selv tak :o)
Avatar billede slapstick Nybegynder
20. september 2005 - 14:35 #11
:D
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester