2008-10-02 9 views
5

Angenommen, ich habe zwei Tabellen, denen ich beitreten möchte. Kategorien:MySQL Query: EIN JOIN LIMITIEREN

id name 
---------- 
1 Cars 
2 Games 
3 Pencils 

und Artikel:

id categoryid itemname 
--------------------------- 
1 1   Ford 
2 1   BMW 
3 1   VW 
4 2   Tetris 
5 2   Pong 
6 3   Foobar Pencil Factory 

ich eine Abfrage möchten, dass die Kategorie und die erste zurückgibt (und nur die erste) itemname:

category.id category.name item.id item.itemname 
------------------------------------------------- 
1   Cars   1  Ford 
2   Games   4  Tetris 
3   Pencils  6  Foobar Pencil Factory 

Und gibt es eine So könnte ich zufällige Ergebnisse erhalten wie:

category.id category.name item.id item.itemname 
------------------------------------------------- 
1   Cars   3  VW 
2   Games   5  Pong 
3   Pencils  6  Foobar Pencil Factory 

Danke!

+0

Wie definieren Sie "First"? Es sieht aus wie der niedrigste ID-Wert in Element? –

+0

Ja, mein Schlechter. Mit ersten meine ich die niedrigste ID. – Eikern

Antwort

6

einfach eine kurze getan Prüfung. Dies scheint zu funktionieren:

mysql> select * from categories c, items i 
    -> where i.categoryid = c.id 
    -> group by c.id; 
+------+---------+------+------------+----------------+ 
| id | name | id | categoryid | name   | 
+------+---------+------+------------+----------------+ 
| 1 | Cars | 1 |   1 | Ford   | 
| 2 | Games | 4 |   2 | Tetris   | 
| 3 | Pencils | 6 |   3 | Pencil Factory | 
+------+---------+------+------------+----------------+ 
3 rows in set (0.00 sec) 

Ich denke, dies ist Ihre erste Frage erfüllen würde. Nicht sicher über den zweiten - ich denke, das braucht eine innere Abfrage mit der Reihenfolge nach dem Zufallsprinzip() oder so ähnlich!

+0

Da die Ergebnisse zufällig sind, ist das für mich nicht so wichtig, also war es genau das, wonach ich gesucht habe! Vielen Dank – Eikern

0

Mysql können Sie Spalten haben, nicht in Gruppierung oder Aggregat enthalten, in welchem ​​Fall sie zufällige Werte haben:

select category.id, category.name, itemid, itemname 
    inner join 
     (select item.categoryid, item.id as itemid, item.name as itemname 
     from item group by categoryid) 
    on category.id = categoryid 

Oder für Minima,

select category.id, category.name, itemid, itemname 
inner join 
    (select item.categoryid, min(item.id) as itemid, item.name as itemname 
    from items 
    group by item.categoryid) 
on category.id = categoryid 
+0

Ich habe einen Fehler bekommen, als ich diese Methode ausprobierte: "Jede abgeleitete Tabelle muss ihren eigenen Alias ​​haben". Ich denke, ich habe irgendwo etwas falsch gemacht. – Eikern

0

Mysql lässt nicht aggregierte Spalten enthalten und es gibt keine Garantie für Determinismus, aber nach meiner Erfahrung bekomme ich fast immer die ersten Werte.

Also in der Regel (aber nicht garantiert) dies wird Ihnen die erste

select * 
from categories c, items i 
where i.categoryid = c.id 
group by c.id; 

Wenn Sie garantiert möchten, müssen Sie so etwas wie

select categories.id, categories.name, items.id, items.name 
from categories inner join 
    items on items.categoryid = categories.id and 
    items.id = (select min(items2.id) from items as items2 where items2.categoryid = category.id) 

tun Wenn Sie zufällige Antworten wollen haben Sie um die Unterabfrage ein wenig zu ändern

select categories.id, categories.name, items.id, items.name 
    from categories inner join 
     items on items.categoryid = categories.id and 
     items.id = (select items2.id from items as items2 where items2.categoryid = category.id order by rand() limit 1)