Avatar billede JJ77 Juniormester
24. april 2006 - 20:23 Der er 36 kommentarer og
1 løsning

Union virker ikke.. nogle forslag?

jeg har nedenstående kode som skal hente nogle oplysninger fra 4 identiske tabeller.. ved godt at 4 ens tabeller ikke altid er optimalt;) men hvordan får jeg nedenstående til at virke, for koden virker perfekt hvis jeg kun henter fra én tabel?

$query = mysql_query("
SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    salgAfProdukt
   
UNION
SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    koebAfProdukt
   
UNION
SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    bytteAfProdukt
   
UNION
SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    bortgivesAfProdukt
   
AS s
   
INNER JOIN
    userProfile AS u
ON
    u.userId = s.userId
WHERE
    ADDDATE(s.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(s.loebetidForAnnonce, INTERVAL -4 DAY) > NOW()
GROUP BY
    u.userEmail
   
") or die(mysql_error());
Avatar billede arne_v Ekspert
24. april 2006 - 20:41 #1
proev med nogle () omkring de rigtige dele
Avatar billede JJ77 Juniormester
24. april 2006 - 20:58 #2
har prøvet, men kunne ikke rigtig finde ud af hvor de skulle være.. for det virkede ihvertfald ikke :(
Avatar billede morhan Novice
24. april 2006 - 21:07 #3
Undersøg også om du benytter MySql version >= 4
Avatar billede JJ77 Juniormester
24. april 2006 - 21:16 #4
det gør jeg:)
Avatar billede JJ77 Juniormester
24. april 2006 - 21:19 #5
og hvorfor kan man ikke bare gøre som nedenstående:

$query = mysql_query("
(SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    salgAfProdukt
   
UNION

    koebAfProdukt
   
UNION

    bytteAfProdukt
   
UNION

    bortgivesAfProdukt)
   
AS s
   
INNER JOIN
    userProfile AS u
ON
    u.userId = s.userId
WHERE
    ADDDATE(s.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(s.loebetidForAnnonce, INTERVAL -4 DAY) > NOW()
GROUP BY
    u.userEmail
   
") or die(mysql_error());
Avatar billede arne_v Ekspert
24. april 2006 - 21:33 #6
syntaxen er

(SELECT ...)
UNION
(SELECT ...)
UNION
(SELECT ...)
Avatar billede arne_v Ekspert
24. april 2006 - 21:38 #7
og jeg er lidt i tvivl om hvor den sidste INNER JOIN passer idn henne

det er bl.a. derfor at nogle parentesser ville pynte
Avatar billede arne_v Ekspert
24. april 2006 - 21:43 #8
hvis du vil joine efter dine unions skal du nok have givet resultatet et
tabel navn (og bruge MySQL 5.0 !)
Avatar billede JJ77 Juniormester
24. april 2006 - 21:55 #9
Har nu prøvet med lidt paranteser, men det virker stadig ikke :(

$query = mysql_query("
(SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    salgAfProdukt)
   
UNION
(SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    koebAfProdukt)
   
UNION
(SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    bytteAfProdukt)
   
UNION
(SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    bortgivesAfProdukt)
   
AS s
   
INNER JOIN
    userProfile AS u
ON
    u.userId = s.userId
WHERE
    ADDDATE(s.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(s.loebetidForAnnonce, INTERVAL -4 DAY) > NOW()
GROUP BY
    u.userEmail
   
") or die(mysql_error());
Avatar billede arne_v Ekspert
24. april 2006 - 22:02 #10
naar du ikke vil fortaelle hvad du mener saa maa jeg jo gaette

jeg gaetter paa at du mener

(
(SELECT ...)
UNION
(SELECT ...)
UNION
(SELECT ...)
) JOIN ...

hvis det er korrekt saa proev:


$query = mysql_query("SELECT * FROM (
(SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    salgAfProdukt)
 
UNION
(SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    koebAfProdukt)
 
UNION
(SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    bytteAfProdukt)
 
UNION
(SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    bortgivesAfProdukt)
) s
 
INNER JOIN
    userProfile AS u
ON
    u.userId = s.userId
WHERE
    ADDDATE(s.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(s.loebetidForAnnonce, INTERVAL -4 DAY) > NOW()
GROUP BY
    u.userEmail
 
") or die(mysql_error());
Avatar billede JJ77 Juniormester
24. april 2006 - 22:12 #11
Nu skal jeg så prøve at forklare mig lidt bedre:) jeg har nedenstående som henter nogle oplysninger fra én tabel hvilket også virker glimrende.. mit problem er at jeg har 4 identiske tabeller, og jeg ville nu gerne have scriptet til at hente oplysninger fra alle 4 på én gang.. håber det hjalp:)




$query = mysql_query("
SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    salgAfProdukt AS s
INNER JOIN
    userProfile AS u
ON
    u.userId = s.userId
WHERE
    ADDDATE(s.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(s.loebetidForAnnonce, INTERVAL -4 DAY) > NOW()
GROUP BY
    u.userEmail
   
") or die(mysql_error());
Avatar billede arne_v Ekspert
24. april 2006 - 22:27 #12
jeps

saa tror jeg at du skal proeve det jeg skitserede i sidste post
Avatar billede JJ77 Juniormester
24. april 2006 - 22:43 #13
giver bare fejlen

You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT u.userEmail, s.loebetidForAnnonce, s.produkt
Avatar billede erikjacobsen Ekspert
24. april 2006 - 22:48 #14
De enkelte SELECT-er skal i hvert fald ikke være
SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    salgAfProdukt

men nærmere (utestet naturligvis):

SELECT
    userEmail,
    loebetidForAnnonce,
    produkt
FROM
    salgAfProdukt
Avatar billede JJ77 Juniormester
24. april 2006 - 22:50 #15
Bemærk at dette virker fint.. så det med u. s. s. er vist ok.. Ikke? men nedenstående virker jo bare kun på én tabel.

$query = mysql_query("
SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    salgAfProdukt AS s
INNER JOIN
    userProfile AS u
ON
    u.userId = s.userId
WHERE
    ADDDATE(s.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(s.loebetidForAnnonce, INTERVAL -4 DAY) > NOW()
GROUP BY
    u.userEmail
   
") or die(mysql_error());
Avatar billede erikjacobsen Ekspert
24. april 2006 - 22:53 #16
Nej, det er ikke ok i din union af 4 select-sætninger, bare fordi det virker i en enkelt join. Der findes ingen u tabel i de "indre" select-sætninger. Så væk med s og u.
Avatar billede erikjacobsen Ekspert
24. april 2006 - 22:56 #17
Desuden skal du finde felterne de rigtige steder. Prøv lige den her (og du må ikke ændre i den)

$query = mysql_query("SELECT * FROM (
(SELECT
    userId,
    loebetidForAnnonce,
    produkt
FROM
    salgAfProdukt)
UNION
(SELECT
    userId,
    loebetidForAnnonce,
    produkt
FROM
    koebAfProdukt)

UNION
(SELECT
    userId,
    loebetidForAnnonce,
    produkt
FROM
    bytteAfProdukt)

UNION
(SELECT
    userId,
    loebetidForAnnonce,
    produkt
FROM
    bortgivesAfProdukt)
) s

INNER JOIN
    userProfile AS u
ON
    u.userId = s.userId
WHERE
    ADDDATE(s.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(s.loebetidForAnnonce, INTERVAL -4 DAY) > NOW()
GROUP BY
    u.userEmail

") or die(mysql_error());
Avatar billede JJ77 Juniormester
24. april 2006 - 23:00 #18
jeg ændrede lige s til AS s, hvis du ved hvor jeg mener:) men får stadig en fejlmedd.


You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT userId, loebetidForAnnonce, produkt FROM
Avatar billede JJ77 Juniormester
24. april 2006 - 23:03 #19
eller skal det der .....FROM
    bortgivesAfProdukt)
) s

skal det kun være et s? men får stadig en fejlmedd.
Avatar billede JJ77 Juniormester
24. april 2006 - 23:05 #20
og hvorfor kan man ikke bare skrive

$query = mysql_query("
SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    (salgAfProdukt, koebAfProdukt, bytteAfProdukt, bortgivesAfProdukt) AS s
INNER JOIN
    userProfile AS u
ON
    u.userId = s.userId
WHERE
    ADDDATE(s.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(s.loebetidForAnnonce, INTERVAL -4 DAY) > NOW()
GROUP BY
    u.userEmail
   
") or die(mysql_error());
Avatar billede erikjacobsen Ekspert
24. april 2006 - 23:08 #21
svar på det sidste er ganske enkelt fordi det er ulovlig syntaks.

Kan du lige fortælle hvilken version af mysql du bruger?
Avatar billede erikjacobsen Ekspert
24. april 2006 - 23:09 #22
Det er tænkeligt at det skal være en kende simplere:

$query = mysql_query("(
(SELECT
    userId,
    loebetidForAnnonce,
    produkt
FROM
    salgAfProdukt)
UNION
(SELECT
    userId,
    loebetidForAnnonce,
    produkt
FROM
    koebAfProdukt)

UNION
(SELECT
    userId,
    loebetidForAnnonce,
    produkt
FROM
    bytteAfProdukt)

UNION
(SELECT
    userId,
    loebetidForAnnonce,
    produkt
FROM
    bortgivesAfProdukt)
) s

INNER JOIN
    userProfile AS u
ON
    u.userId = s.userId
WHERE
    ADDDATE(s.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(s.loebetidForAnnonce, INTERVAL -4 DAY) > NOW()
GROUP BY
    u.userEmail

") or die(mysql_error());
Avatar billede erikjacobsen Ekspert
24. april 2006 - 23:10 #23
Nej, det du heller ikke. Kan du ikke lige forklare hvad du vil opnå med din GROUP BY ?
Avatar billede JJ77 Juniormester
24. april 2006 - 23:17 #24
MySql ver=  4.0.24

det er fordi en bruger kan oprette annoncer i flere tabeller.. hvis han fx har annoncer i 2 af tabellerne skal han ikke modtage 2 mails kun én, så derfor..
Avatar billede erikjacobsen Ekspert
24. april 2006 - 23:20 #25
Nej, det er altså ikke forklaring på din GROUP BY. Det er jo ikke bare noget man sætter på for sjov, fordi mysql så kan gætte hvad du vil. Hvad er det du vil opnå med den? Hvilket resultat - gerne et eksempel.

Så kan vi nok, måske, komme op med noget der virker i mysql 4.1 - men jeg kan ikke i mysql 4.0, desværre.

Jeg kan sikkert i mysql 4.0 hvis du smider de 4 tabeller sammen i een.

Eller hvis du vil bruge mere end een sql-sætning.

Det hele kræver lige at du forklarer hvad du vil.
Avatar billede JJ77 Juniormester
24. april 2006 - 23:27 #26
Jeg kan desværre ikke ændre min mySql version:( og jeg kan ikke samle de 4 tabeller i én:( og som det er nu virker nedenstående kode, men kun når den skal arbejde med én tabel. Hva fann gør jeg så?

$query = mysql_query("
SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    salgAfProdukt AS s
INNER JOIN
    userProfile AS u
ON
    u.userId = s.userId
WHERE
    ADDDATE(s.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(s.loebetidForAnnonce, INTERVAL -4 DAY) > NOW()
GROUP BY
    u.userEmail
   
") or die(mysql_error());

if (mysql_num_rows($query) > 0)
{
    $subject = 'Annoncer udløber på xxx.dk';
    $headers = 'From: robot@xxx.dk' . "\n" . //skal være en xxx.dk mailadresse, ellers kan den maks sende 1 mail pr. minut.
    'Reply-To: From: robot@xxx.dk' . "\n" .
    'X-Mailer: PHP/' . phpversion();
   
    while($row = mysql_fetch_assoc($query))
    {
        $to      = $row['userEmail'];
        $message = 'Du har annoncer på xxx.dks hjemmeside, som udløber inden for de næste dage. Du kan forlænge dine annoncers løbetid hvis du logger ind på hjemmesiden og går ind under "Min konto", ellers vil de blive slettet ved udløb.' . "\n\n";
        $message .= 'Med venlig hilsen xxx.dk' . "\n\n\n";
        $message .= '------------------------------------------' . "\n";
        $message .= 'PS: denne email er udsendt automatisk og kan derfor ikke besvares. Benyt i stedet kontaktmulighederne på xxx.dk' . "\n";
       
        if(mail($to, $subject, $message, $headers))
        {
            echo "EMAIL AFSENDT<br />";
        }
        else
        {
            echo "FEJL<br />";
        }
    }
}
else
{
    echo "Ingen annoncer udløber om 4-5 dage";
}
Avatar billede JJ77 Juniormester
24. april 2006 - 23:38 #27
og burde man egentlig ikke kunne løse det således?

$query = mysql_query("SELECT * FROM(
SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    salgAfProdukt AS s
INNER JOIN
    userProfile AS u
ON
    u.userId = s.userId
WHERE
    ADDDATE(s.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(s.loebetidForAnnonce, INTERVAL -4 DAY) > NOW())

UNION
(
SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    koebAfProdukt AS s
INNER JOIN
    userProfile AS u
ON
    u.userId = s.userId
WHERE
    ADDDATE(s.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(s.loebetidForAnnonce, INTERVAL -4 DAY) > NOW())

UNION
(
SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    bytteAfProdukt AS s
INNER JOIN
    userProfile AS u
ON
    u.userId = s.userId
WHERE
    ADDDATE(s.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(s.loebetidForAnnonce, INTERVAL -4 DAY) > NOW())

UNION
(
SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    bortgivesAfProdukt AS s
INNER JOIN
    userProfile AS u
ON
    u.userId = s.userId
WHERE
    ADDDATE(s.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(s.loebetidForAnnonce, INTERVAL -4 DAY) > NOW())


GROUP BY
    u.userEmail
   
") or die(mysql_error());
Avatar billede erikjacobsen Ekspert
24. april 2006 - 23:44 #28
Som sagt: du kan bruge mere end een sql-sætning og ordne resten i PHP. Men ikke mere hjælp fra mig - jeg gider ikke hjælpe personer, der bander.
Avatar billede JJ77 Juniormester
24. april 2006 - 23:51 #29
hov hov:) så lader jeg være med at bande... det ville være fint hvis det kunne løses med flere sql-sætninger:)
Avatar billede JJ77 Juniormester
24. april 2006 - 23:52 #30
Men kan godt forstå hvis du ikke gider mere.. Det er ikke en af de nemme, indrømmet:). Hvis det er, er du velkommen til at smide et svar så du kan få dine point. Jeg kan også sætte dem lidt op hvis det hjælper?
Avatar billede eagleeye Praktikant
24. april 2006 - 23:52 #31
Skal du kun havde email adressen ud?
Avatar billede JJ77 Juniormester
25. april 2006 - 00:06 #32
ja. Nedenstående virker, men kun på én tabel.. Skal bare virke så den kan hente fra 4 tabeller på én gang, eller hvordan man nu kan gøre det:)

$query = mysql_query("
SELECT
    u.userEmail,
    s.loebetidForAnnonce,
    s.produkt
FROM
    salgAfProdukt AS s
INNER JOIN
    userProfile AS u
ON
    u.userId = s.userId
WHERE
    ADDDATE(s.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(s.loebetidForAnnonce, INTERVAL -4 DAY) > NOW()
GROUP BY
    u.userEmail
   
") or die(mysql_error());

if (mysql_num_rows($query) > 0)
{
    $subject = 'Annoncer udløber på xxx.dk';
    $headers = 'From: robot@xxx.dk' . "\n" . //skal være en xxx.dk mailadresse, ellers kan den maks sende 1 mail pr. minut.
    'Reply-To: From: robot@xxx.dk' . "\n" .
    'X-Mailer: PHP/' . phpversion();
   
    while($row = mysql_fetch_assoc($query))
    {
        $to      = $row['userEmail'];
        $message = 'Du har annoncer på xxx.dks hjemmeside, som udløber inden for de næste dage. Du kan forlænge dine annoncers løbetid hvis du logger ind på hjemmesiden og går ind under "Min konto", ellers vil de blive slettet ved udløb.' . "\n\n";
        $message .= 'Med venlig hilsen xxx.dk' . "\n\n\n";
        $message .= '------------------------------------------' . "\n";
        $message .= 'PS: denne email er udsendt automatisk og kan derfor ikke besvares. Benyt i stedet kontaktmulighederne på xxx.dk' . "\n";
       
        if(mail($to, $subject, $message, $headers))
        {
            echo "EMAIL AFSENDT<br />";
        }
        else
        {
            echo "FEJL<br />";
        }
    }
}
else
{
    echo "Ingen annoncer udløber om 4-5 dage";
}
Avatar billede eagleeye Praktikant
25. april 2006 - 00:15 #33
Det var bare en tanke men hvis union ikke virker kunne man måske "vende" det om og lave left join ud fra userProfile eks:


$query = mysql_query("
SELECT userEmail
FROM (((userProfile as u LEFT JOIN salgAfProdukt as t1 ON u.id = t1.userId)
LEFT JOIN koebAfProdukt as t2 ON u.id = t2.userId)
LEFT JOIN bytteAfProdukt as t3 ON u.id = t3.userId)
LEFT JOIN bortgivesAfProdukt as t4 ON u.id = t4.userId
WHERE
    (ADDDATE(t1.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(t1.loebetidForAnnonce, INTERVAL -4 DAY) > NOW())
OR
    (ADDDATE(t2.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(t2.loebetidForAnnonce, INTERVAL -4 DAY) > NOW())
OR
    (ADDDATE(t3.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(t3.loebetidForAnnonce, INTERVAL -4 DAY) > NOW())
OR
    (ADDDATE(t4.loebetidForAnnonce, INTERVAL -5 DAY) < NOW()
AND
    ADDDATE(t4.loebetidForAnnonce, INTERVAL -4 DAY) > NOW())
") or die(mysql_error());
Avatar billede JJ77 Juniormester
25. april 2006 - 00:20 #34
hehe.. det ser jo helt vandvittigt ud.. kan desværre ikke nå at teste det i aften, der presses fra anden side.. men prøver lige i morgen.. skal nok vende tilbage..:) nat nat
Avatar billede JJ77 Juniormester
01. maj 2006 - 15:41 #35
Har droppet det.. men tak for hjælpen, så smid i bare et svar så i kan få nogle point;-)
Avatar billede arne_v Ekspert
02. maj 2006 - 00:54 #36
jeg frafalder
Avatar billede JJ77 Juniormester
10. maj 2006 - 16:10 #37
ok.. men tak for hjælpen.. så snupper jeg da pointene selv
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
Computerworld tilbyder specialiserede kurser i database-management

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