Avatar billede Mik2000 Professor
17. maj 2009 - 18:12 Der er 23 kommentarer og
1 løsning

Mysql sætning - hvordan

Hej

Jeg har en database kaldet projekter
Denne har felterne:
id
ugenr
stednr
personnr
afdeling
projektnavn

Jeg skal hente fra denne:
1: Således at den henter alle fra en uge
2: Dem den henter i 1 skal deles således at de inddeles i stednr, så dem med lavest stednr kommer samlet først
3: Dem der er hentet skal inden for hvert stednr inddeles således, at dem der har et afdelingsnummer (som jeg har i en variabel), der er lig med afdeling i tabellen kommer først
4: De skal derefter sorteres så dem med laveste personnr kommer først

Omskrevet på en anden måde, for det er til at forstå:
Først hentes dem fra en uge

Derefter sorteres i klumper efter stednr (som om det er hver projekt)

Hver af disse "klumper" skal så sorteres så dem med afdeling der matcher en variabel med et nummer jeg har, kommer først

Dem der har sådan en afdeling skal sorteres efter personnr med det laveste først, og dem uden skal også sorteres efter personnr med det laveste først


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

Håber I forstår, ellers spørger I bare.
Jeg håber en kan gennemskue det. På forhånd tak.

Ps. Det er ikke muligt at ændre på database struktur og lign.
Avatar billede acore Ekspert
17. maj 2009 - 21:02 #1
Antager at du har ugenr i $ugenr og afdelingsnummer i $afdno (og bruger PHP) samt at din tabel hedder xxx:

SELECT *, CASE WHEN afdeling='$afdno' THEN 1 ELSE 0 AS afd_match
FROM xxx
WHERE ugenr='$ugenr'
ORDER BY stednr ASC, afd_match DESC, personnr ASC
Avatar billede Mik2000 Professor
17. maj 2009 - 21:52 #2
Rigtig mange tak for svaret.....

Nu blev det dog lige endnu mere kompliceret fandt jeg ud af, så håber du kan hjælpe her også for jeg er stået af ;). Dobler gerne pointene hvis det er :)

Det er sådan at afdeling ikke findes i en variabel som jeg troede. Det er i stedet i en anden tabel :(

Så det er hvis afdeling i den oprindelige tabel, matcher afdeling i en anden tabel, hvor id'et i den anden tabel er magen til stednr

--------

Prøver lige at pensle det lidt ud (den med * er ny/ændret):
Først hentes dem fra en uge

Derefter sorteres i klumper efter stednr (som om det er hver projekt)

* Hver af disse "klumper" skal så sorteres så dem med afdeling der matcher afdeling i anden tabel kommer først. Afdeling skal matche afdeling i den anden tabel, hvor id'et er lig med stednr
(dvs stednr er fremmednøgle til den anden tabels id eller hvad det hedder)

Dem der har sådan en afdeling skal sorteres efter personnr med det laveste først, og dem uden skal også sorteres efter personnr med det laveste først

--------

Håber det er muligt overhovedet
Avatar billede acore Ekspert
17. maj 2009 - 22:28 #3
SELECT *, ifnull(t2.afdeling, 99999) AS afd_match
FROM xxx AS t1
LEFT JOIN yyy AS t2 ON (t1.afdeling = t2.afdeling)
WHERE ugenr='$ugenr'
ORDER BY t1.stednr ASC, afd_match DESC, t1.personnr ASC

Antager at den nye tabel hedder yyy og af feltet hedder afdeling i dem begge. Samt at der ikke er nogen afdeling højere end 99999.

PS. Ikke testet, så jeg garantere ikke ;)
Avatar billede Mik2000 Professor
17. maj 2009 - 23:03 #4
Mange tak :)

Den skriver ugenr ikke er tydligt, så prøvede med:
WHERE t1.ugenr='$ugenr' som det ses herunder

SELECT *, ifnull(t2.afdeling, 99999) AS afd_match
FROM xxx AS t1
LEFT JOIN yyy AS t2 ON (t1.afdeling = t2.afdeling)
WHERE t1.ugenr='$ugenr'
ORDER BY t1.stednr ASC, afd_match DESC, t1.personnr ASC

Men hvis jeg kører den, og der er 2 poster i xxx tabellen som skal sorteres, så returnere den 16 poster
Lige som om den henter noget fra yyy tabellen med i som egentlig kun skal bruges til match, for at finde ud af sortering

Jeg skal lige sige at afdeling i xxx tabellen godt kan matche afdeling mange steder i yyy tabellen.
Den skal tjekke om t1.afdeling = t2.afdeling der hvor t1.stednr (tabel xxx) er lig med t2.id (tabel yyy)

Tror det er det der går galt, men kan ikke gennemskue hvordan det ændres
Avatar billede acore Ekspert
18. maj 2009 - 08:20 #5
Det er derfor. Du skal have en DISTINCT med:

SELECT DISTINCT *, ifnull(t2.afdeling, 99999) AS afd_match
FROM xxx AS t1
LEFT JOIN yyy AS t2 ON (t1.afdeling = t2.afdeling)
WHERE t1.ugenr='$ugenr'
ORDER BY t1.stednr ASC, afd_match DESC, t1.personnr ASC

Det er altid en god ide at give tabel-struktur og sammenhænge mellem alle relevante tabeller. Det bliver nemmere at svare, og svarene bliver mere præcise.
Avatar billede Mik2000 Professor
18. maj 2009 - 19:23 #6
Hej

Tak for din store tålmodighed. Det resultere dog stadig i 16 rækker

Tabel xxx
id int autoinc unique
stednr int 11 (svarer til id i tabel yyy)
ugenr int 11
personnr int 11
afdeling int 11
projektnavn varchar 200

Tabel yyy
id int autoinc unique
afdeling int 11
... samt nogle andre felter der nok ikke har interesse

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

Der er pt 2 rækker i tabel xxx (begge rækker har samme stedid)
Der er pt 140 rækker i tabel yyy

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

Håber stadig du vil hjælpe
Avatar billede acore Ekspert
19. maj 2009 - 09:48 #7
Jo da - så længe det går fremad. Og her er det min fejl - undskyld.

DISTINCT sørger for, at der ikke kommer ens rækker. Derfor afhænger resultatet af hvilke felter man tager med. Og jeg har taget dem allesammen (*), hvorfor det ikke virker.

Du skal derfor nøjes med de felter fra tabel xxx, du skal bruge:

SELECT DISTINCT t1.*, ifnull(t2.afdeling, 99999) AS afd_match
FROM xxx AS t1
LEFT JOIN yyy AS t2 ON (t1.afdeling = t2.afdeling)
WHERE t1.ugenr='$ugenr'
ORDER BY t1.stednr ASC, afd_match DESC, t1.personnr ASC
Avatar billede Mik2000 Professor
21. maj 2009 - 01:06 #8
Super så ser det rigtigt ud - mange mange mange tak :)

Der er lige en ting mere jeg har fundet ud af, og det er er at:

Når der sorteres på afdeling skal dem hvor det er samme afdeling være højest (er lavet), derefter skal dem hvor afdeling ikke er 0 komme (mangler), og herefter resten.

Kan du hjælpe med dette også. Så er den endelig færdig...

Havde aldrig fundet ud af det uden din hjælp :)
Avatar billede acore Ekspert
21. maj 2009 - 09:05 #9
Dejligt, at du er i hus (næsten) og ikke mindst er glad for løsningen. Den sidste lille vej:

SELECT DISTINCT t1.*, ifnull(t2.afdeling, if(t2.afdeling = 0, 99998, 99999)) AS afd_match
FROM xxx AS t1
LEFT JOIN yyy AS t2 ON (t1.afdeling = t2.afdeling)
WHERE t1.ugenr='$ugenr'
ORDER BY t1.stednr ASC, afd_match DESC, t1.personnr ASC

Efterhånden som du lærer SQL så kan jeg anbefale manualen på http://dev.mysql.com/doc/refman/5.1/en/index.html. Den er på engelsk og ikke lige så god og pædagogisk som fx PHP manualen, men den er en guldgrube af informationer.
Avatar billede Mik2000 Professor
21. maj 2009 - 12:15 #10
Hej

Endnu engang mange tak. Den gør det dog ikke helt rigigt endnu, da dem med afdelingsnummer 0 kommer før dem der har et afdelingnummer
Avatar billede Mik2000 Professor
21. maj 2009 - 22:42 #11
Kan i øvrigt ikke finde det sted man lægger flere point til. Ved du hvor det er, ellers må vi oprette et ekstra spørsmål
Avatar billede Mik2000 Professor
22. maj 2009 - 10:55 #12
Kan ikke lige gennemskue hvad der skal ændres - heller ikke efter læsning på det link du gav, men skal nok også starte mere stille.

Men den placere stadig dem med 0 i afd i xxx tabellen over dem der har andet tal i afd i xxx tabellen
Avatar billede Mik2000 Professor
23. maj 2009 - 15:51 #13
Jeg har givet dig point, for hjælpen, men håber stadig du lige har tid til at få det sidste med, så vil je være superglad :)
Avatar billede acore Ekspert
24. maj 2009 - 12:31 #14
Nyt forsøg fra min side:

SELECT DISTINCT t1.*, ifnull(t2.afdeling, if(t1.afdeling = 0, 99998, 99999)) AS afd_match
FROM xxx AS t1
LEFT JOIN yyy AS t2 ON (t1.afdeling = t2.afdeling)
WHERE t1.ugenr='$ugenr'
ORDER BY t1.stednr ASC, afd_match ASC, t1.personnr ASC

Det med flere point er ligemeget. Men dejligt, at du kan bruge hjælpen. Det har været svært at følge med, for mail-notificeringen er vist ude af drift.
Avatar billede Mik2000 Professor
04. juni 2009 - 01:44 #15
Hej
Troede den fungerede men har først fået prøvet den rigtigt nu

Eksempelvis så er der et stednummer, hvor ingen afdeling matcher, men hvor det virker som om de andre sorteres efter afdelingsnummer, da en der bor i en afdeling kommer før en som bor i afdeling med højere nummer, selvom denne har lavere personnr.

Det skal jo være sådan omkring det med afdelinger:
1: Først dem med samme afd nummer (hvor de matcher)
2: Så dem der bare har et afdelingsnummer
3: Så dem med afd nummer der er lig 0

Men inden for hver af disse er det det næste parameter der afgør hvad der kommer først dvs. personnr, og ikke f.eks. nummeet på afdelingen

Kan du hjælpe med dette også :)
Giver gerne flere point eller lign :)
Avatar billede acore Ekspert
04. juni 2009 - 17:12 #16
Jeg er her da endnu...

ORDER BY t1.stednr ASC, afd_match ASC, t1.personnr ASC

Betyder, at først sorterer den efter stednr (det er ok), så efter afd_match (det vender jeg tilbage til) og til slut efter personnr (det er også ok).

Opgaven er således at sørge for, at afd_match indeholder fx 1 hvis der er match på afdeling, 2 hvis der er en afdeling men intet match og 3 ellers. Så spiller det.

Det er bare ikke det, der sker nu. Dvs. definitionen af indholet i afd_match skal ændres:

SELECT DISTINCT t1.*, IF(ISNULL(t2.afdeling), IF(t1.afdeling = 0, 3, 2), 1) AS afd_match
FROM xxx AS t1
LEFT JOIN yyy AS t2 ON (t1.afdeling = t2.afdeling)
WHERE t1.ugenr='$ugenr'
ORDER BY t1.stednr ASC, afd_match ASC, t1.personnr ASC
Avatar billede Mik2000 Professor
05. juni 2009 - 00:01 #17
Hej

Mange tak for din forsatte hjælp :) Ved ikke hvad jeg skulle gøre uden :)

Så ser det bedre ud

Men der er stadig en smutter

Har 4 stk der ikke matcher afdeling, men hvor der er en afdeling på alle
De har følgende personnr, som der så burde være sorteret efter
539001
721100
1142800
830200
Og sorteres i den rækkefølge som de ses herover. Dvs at den sætter 1142800 til at være mindre end 830200

Begge de andre søgekriterier er ens da dehar samme stednr og da de begge tilhører en afdeling som ikke matcher
Avatar billede acore Ekspert
05. juni 2009 - 00:29 #18
Man kommer langt med stædighed ;)

Tja, det ved jeg ikke. Min eneste bud er, at de er repræsenteret som tekst og ikke tal, og sorteres derefter, men det tror jeg ikke engang selv på, for så ville 1142800 komme først.

Tror derfor at fejlen ligger et andet sted. Her er et par ideer, hvis jeg skulle fejlsøge det:

Hvad er datatypen?
Kan det være noget med "nul" versus bostavet "o"?
Er du helt sikker på, at de andre sorteringskriterier er ens?
Prøv at kør

SELECT * from xxx WHERE personnr IN(539001,721100,1142800,830200) ORDER BY personnr

Kommer de allesammen ud? Og i hvilken rækkefølge?
Avatar billede Mik2000 Professor
07. juni 2009 - 17:06 #19
Hmm meget mærkeligt - de kommer i den rigtige rækkefølge når jeg benytter den du skrev til sidst
Avatar billede acore Ekspert
07. juni 2009 - 17:12 #20
Kik på de andre spørgsmål jeg rejser i #18
Avatar billede Mik2000 Professor
07. juni 2009 - 17:15 #21
Hvis jeg fjerner:
afd_match ASC,
i ORDER BY sætningen
... så kommer de også efter personnr
Avatar billede Mik2000 Professor
07. juni 2009 - 17:16 #22
Det er 0 i
Datatype er int(11) på personnr
Avatar billede Mik2000 Professor
07. juni 2009 - 17:29 #23
Hmm nu kan jeg se problemet

"Opgaven er således at sørge for, at afd_match indeholder fx 1 hvis der er match på afdeling, 2 hvis der er en afdeling men intet match og 3 ellers. Så spiller det."

Afdeling match er 1 på de første 3, mens det er 2 på de næste og 3 på de sidste

Der kigges pt på afdeling 8
Dem der har afdeling 18, 22 og 30 har fået 1 i afd_match
Dem der har afdeling 50 har fået 2 i afd_match
Dem uden afdeling har fået 3 i afd_match

Så på en eller anden måde siger den at 50 = 8
Den skal kigge i t2 det sted hvor t1.stednr er lig med t2.id - og tjekke om t1.afdeling er lig med t2.afdeling

Men hvor fortæller vi at den skal kigge i t2 det sted hvor t1.stednr er lig med t2.id ?
Avatar billede Mik2000 Professor
07. juni 2009 - 20:09 #24
Hvis du hjælper mig så den virker vil jeg evt også gerne betale lidt penge for alt den hjælp :)
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
Vi tilbyder markedets bedste kurser inden for webudvikling

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