Avatar billede supermand69 Nybegynder
14. september 2004 - 21:26 Der er 14 kommentarer og
1 løsning

left join

jeg vil lave en søgning blandt nogle brugere...

min struktur:
user
id | name | ...

music
user_id | music

jeg vil så søge blandt brugere der har to rækker i tabellen 'music' hvor feltet 'music' indeholder 5 og 6

SELECT user.id
FROM db.user user
LEFT JOIN db.user_music music ON user.id=music.user_id
WHERE music.music='5' && music.music='6'
GROUP BY user.id
Avatar billede arne_v Ekspert
14. september 2004 - 21:31 #1
SELECT user.id
FROM db.user user,db.user_music music1,db.user_music music2
WHERE user.id=music1.user_id AND user.id=music2.user_id AND music1.music='5' AND music2.music='6'
GROUP BY user.id
Avatar billede supermand69 Nybegynder
14. september 2004 - 21:35 #2
jamen det er ikke sikkert at der overhovedet eksisterer en række med en af de to værdier... så det skal vel være outer join? eller hvad det hedder? :)
Avatar billede arne_v Ekspert
14. september 2004 - 21:38 #3
En left eller anden outer join gør at der vises rækker selvom der ikke
er noget der matcher i en eller flere af tabellerne.

Jeg kan ikke se at det skal bruges her.
Avatar billede supermand69 Nybegynder
14. september 2004 - 21:47 #4
jamen det kan jo ogaå være at der skal være mere end to værdier... der er blandt andet to tables mere som user_music med delte primær nøgler :) user_interests og user_music2

hvis jeg nu vælger en værdi den skal søge efter fra hver af de andre tre tables (user_music, user_interests. iser_music2) viker det fint, men så snart jeg vælger flere værdier til hver table går det galt?

her er hele min kode til søgefunktionen

if($_POST['action'])
{
    $table = "$DB.user user";
    $where = "user.active=1";
   
    if($_GET['tab'] == 'user')
    {
        if($_POST['sex'] == 'm') $where .= " && user.sex=0";
        elseif($_POST['sex'] == 'k') $where .= " && user.sex=1";
       
        if($_POST['pic']) $where .= " && user.pic!=''";
       
        if($_POST['area']) $where .= " && user.area='$_POST[area]'";
       
        if($_POST['added']) $where .= " && user.added>'$_POST[added]'";
       
        if($_POST['last_log']) $where .= " && user.last_log>'$_POST[last_log]'";
       
        if($_POST['seek']) $where .= " && user.seek='$_POST[seek]'";
       
        if($_POST['status']) $where .= " && user.status='$_POST[status]'";
       
        if($_POST['age1']) $where .= " && YEAR(SUBTIME(CURDATE(), user.birth))>='$_POST[age1]'";
        if($_POST['age2']) $where .= " && YEAR(SUBTIME(CURDATE(), user.birth))<='$_POST[age2]'";
       
        if($_POST['zip']) $where .= " && user.zip='$_POST[zip]'";
       
        if($_POST['music'])
        {
            $join = " LEFT JOIN $DB.user_music music ON user.id=music.user_id";
           
            if($i) $from = "($from) ".$join;
            else $from = "$table $join";
           
            foreach($_POST['music'] as $value) $where .= " && music.music='$value'";
           
            $i = 1;
        }
       
        if($_POST['music2'])
        {
            $join = " LEFT JOIN $DB.user_music2 music2 ON user.id=music2.user_id";
           
            if($i) $from = "($from)".$join;
            else $from = "$table $join";
           
            foreach($_POST['music2'] as $value) $where .= " && music2.music='$value'";
           
            $i = 1;
        }
       
        if($_POST['interests'])
        {
            $join = " LEFT JOIN $DB.user_interests interests ON user.id=interests.user_id";
           
            if($i) $from = "($from)".$join;
            else $from = "$table $join";
           
            foreach($_POST['interests'] as $value) $where .= " && interests.interests='$value'";
           
            $i = 1;
        }
       
        if($i) $from = $from;
    }
    elseif($_GET['tab'] == 'name')
    {
        if($_POST['type'] == 1) $where .= " && name LIKE '%$_POST[name]%'";
        elseif($_POST['type'] == 2) $where .= " && name LIKE '$_POST[name]%'";
        elseif($_POST['type'] == 3) $where .= " && name LIKE '%$_POST[name]'";
    }
   
    if(!$from) $from = $table;
   
    $sql = "SELECT user.id FROM $from WHERE $where GROUP BY user.id ORDER BY user.time DESC";
}
Avatar billede arne_v Ekspert
14. september 2004 - 22:20 #5
Du kan vel også lave den med LEFT JOIN.

Du skal stadig have music tabellen joinet ind det samme antal gange som du har
værdier (i det oprindelige spørgsmål 2 gange).
Avatar billede supermand69 Nybegynder
14. september 2004 - 22:26 #6
jeg er ikke helt med på hvad du mener med at jeg stadig skal have music tablen joinet ind det samme antal gange som jeg har værdier?

den bliver da kun joinet en gang? :)
Avatar billede arne_v Ekspert
14. september 2004 - 22:27 #7
Hvis du kigger i min query 14/09-2004 21:31:02 vil du se at music tabellen er
inde 2 gange
Avatar billede supermand69 Nybegynder
14. september 2004 - 22:28 #8
nå ja ok...er med nu...

men jeg kan stadig ikke få min query til at virke hvis man vælger mere end en værdi for hver joindet table :(
Avatar billede supermand69 Nybegynder
15. september 2004 - 17:48 #9
jeg troede bare godt at dette kunne lade sig gøre:

SELECT user.id
FROM db.user user
LEFT JOIN db.user_music music ON user.id=music.user_id
WHERE music.music='5' && music.music='6'
GROUP BY user.id

men det vil altså sige at man skal lave join for hver værdi man vil søge efter, selvom det er i den samme table man joiner man søger i??
Avatar billede arne_v Ekspert
15. september 2004 - 18:43 #10
Ja - fordi det er forskellige records de værdier du tester på ligger i !

(normalt er det ikke nødvendigt, men det er fordi de forskellige betingelser
tester på værdier i samme række)
Avatar billede supermand69 Nybegynder
15. september 2004 - 18:52 #11
altså... det vil sige hvis min table jeg joiner ser således ud:

user_music
user_id | music | test

- og jeg også ville søge på noget i feltet 'test'? så kunne jeg godt gøre det hele i en join??
Avatar billede arne_v Ekspert
15. september 2004 - 18:55 #12
Du kan sagtens teste på om felt A er X og felt B er Y i samme række uden
sådan en self join.

Den er kun nødvendig hvis du vil finde noget der har en række med felt A = X1
og også har en anden række med felt A = X2.
Avatar billede supermand69 Nybegynder
15. september 2004 - 18:55 #13
altså søge efter EN værdi i music og EN i test :)
Avatar billede arne_v Ekspert
15. september 2004 - 18:56 #14
Hvis det er samme række så er det bare en gange user_music tabel
og WHERE music=X AND test=Y
Avatar billede supermand69 Nybegynder
15. september 2004 - 19:00 #15
tak for hjælpen :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
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