Prosta instrukcja wyboru nie zwracająca poprawnych danych


1

Próbuję zwrócić dane, gdzie chcę nazwę przedmiotu (item.name), nazwę dostawcy (vendors.name), url ceny (prices.url) i cenę (prices.price) z 3 różnych tabel (przedmioty, sprzedawcy i ceny) przy użyciu klucza obcego vid (identyfikator dostawcy) z prices.vid i vendors.vid i pokazując tylko wyniki z identyfikatorem przedmiotu 3 (items.iid = '3'), ale otrzymuję wyniki z różnych identyfikatorów pozycji dobrze.

Oto jak wyglądają tabele:

mysql> describe prices;
+-------+------------------------+------+-----+---------+----------------+
| Field | Type          | Null | Key | Default | Extra     |
+-------+------------------------+------+-----+---------+----------------+
| pid  | int(10) unsigned    | NO  | PRI | NULL  | auto_increment |
| price | decimal(10,2) unsigned | YES |   | NULL  |        |
| url  | longtext        | YES |   | NULL  |        |
| iid  | int(10) unsigned    | NO  | MUL | NULL  |        |
| vid  | tinyint(3) unsigned  | NO  | MUL | NULL  |        |
+-------+------------------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)


mysql> select * from items;
| iid | name           | scid | desc                                                                                                               
|  1 | Ahtanum         |  3 | Ahtanum is ... 
|  2 | Amarillo         |  3 | Amarillo is ...                                       
|  3 | 22 oz Beer Bottles Amber |  56 | 22 ounce amber...


mysql> select * from prices;
+-----+-------+--------------------------------------------------------------------------------------+-----+-----+
| pid | price | url                                           | iid | vid |
+-----+-------+--------------------------------------------------------------------------------------+-----+-----+
|  1 | 3.50 | homebrewhaven.com/id=10                                   |  2 |  4 |
|  2 | 4.50 | morebeer.com/id=15                                    |  2 |  7 |
|  3 | 11.99 | http://www.northernbrewer.com/default/beer-bottles-22-oz.html              |  3 |  1 |
|  4 | 14.99 | http://www.austinhomebrew.com/product_info.php?products_id=993            |  3 |  2 |
|  5 | 12.50 | http://www.midwestsupplies.com/22-oz-bottles-amber-case-of-12.html          |  3 |  3 |
|  6 | 14.50 | http://store.homebrewheaven.com/22-oz-brown-beer-bottles-case-of-12-bottles-p69.aspx |  3 |  4 |
|  7 | 12.95 | http://morebeer.com/view_product/15630//Bottles_-_22_oz_12                |  3 |  7 |
|  8 | 14.99 | http://www.brewmasterswarehouse.com/product/0101545/case-22-oz-beer-bottle-amber   |  3 |  9 |
+-----+-------+--------------------------------------------------------------------------------------+-----+-----+

Teraz, gdy wykonam zapytanie:

SELECT distinct items.name, vendors.name, prices.url, prices.price 
FROM vendors, prices, items 
WHERE vendors.vid = prices.vid AND items.iid='3' 
ORDER BY prices.price;

W moim wyniku otrzymuję także 1 i 2 cenę id, mimo że iid (id przedmiotu) to 2, a nie 3, jak chcę w zapytaniu .... Wyniki poniżej:

mysql> select distinct items.name, vendors.name, prices.url, prices.price FROM vendors, prices, items WHERE vendors.vid = prices.vid AND items.iid='3' ORDER BY prices.price;
+--------------------------+-----------------------+--------------------------------------------------------------------------------------+-------+
| name           | name         | url                                           | price |
+--------------------------+-----------------------+--------------------------------------------------------------------------------------+-------+
| 22 oz Beer Bottles Amber | Homebrew Heaven    | homebrewhaven.com/id=10                                 | 3.50 |
| 22 oz Beer Bottles Amber | More Beer       | morebeer.com/id=15                                    | 4.50 |
| 22 oz Beer Bottles Amber | Nothern Brewer    | http://www.northernbrewer.com/default/beer-bottles-22-oz.html              | 11.99 |
| 22 oz Beer Bottles Amber | Midwest Supplies   | http://www.midwestsupplies.com/22-oz-bottles-amber-case-of-12.html            | 12.50 |
| 22 oz Beer Bottles Amber | More Beer       | http://morebeer.com/view_product/15630//Bottles_-_22_oz_12                | 12.95 |
| 22 oz Beer Bottles Amber | Homebrew Heaven    | http://store.homebrewheaven.com/22-oz-brown-beer-bottles-case-of-12-bottles-p69.aspx | 14.50 |
| 22 oz Beer Bottles Amber | Austin Homebrew    | http://www.austinhomebrew.com/product_info.php?products_id=993              | 14.99 |
| 22 oz Beer Bottles Amber | Brewmasters Warehouse | http://www.brewmasterswarehouse.com/product/0101545/case-22-oz-beer-bottle-amber     | 14.99 |
+--------------------------+-----------------------+--------------------------------------------------------------------------------------+-------+
8 rows in set (0.04 sec)

Jak widać, otrzymuję dwa pierwsze wyniki, które mają iid = 2, a nie 3. Wszystkie pozostałe powinny pojawić się, ale nie te pierwsze dwa.

Jakieś pomysły, co się dzieje?

+1

Twoja tabela przedmiotów nie jest poprawnie połączona z innymi.Przepisz zapytanie za pomocą składni ANSI, a problem stanie się jaśniejszy. 14 wrz. 112011-09-14 16:45:08

+1

Na przykład: SELECT DISTINCT i.name, v.name, p.url, p.price FROM vendor v INNER JOIN ceny p ON v.vid = p.vid INNER JOIN elementy i ON p.iid = i.iid WHERE i. iid = '3' ORDER BY p.price; 14 wrz. 112011-09-14 16:49:52

  0

To działa!Dzięki! 14 wrz. 112011-09-14 17:04:02

+2

To naprawdę powinno być zadane w [tak] 14 wrz. 112011-09-14 18:41:26

5

Brakuje Ci DOŁĄCZENIA między cenami i przedmiotami.

Twoje niejawne połączenie w klauzuli where łączy tylko dostawców i ceny, więc otrzymujesz połączenie kartezjańskie dla wyniku tego połączenia i tabeli elementów.Jeśli zamiast tego użyłbyś słów kluczowych ANSI JOIN, zauważyłbyś to natychmiast

Potrzebujesz czegoś takiego:

select distinct items.name, 
       vendors.name, 
       prices.url, 
       prices.price 
    FROM vendors
     JOIN prices ON vendors.vid = prices.vid 
     JOIN items ON items.iid = prices.iid --- this part is missing
    WHERE items.iid='3' 
ORDER BY prices.price;

Nie wiem, czy warunek łączenia jest poprawny, ponieważ nie powiedziałeś nam, która kolumna w cenach zawiera klucz obcy do przedmiotów.

  0

To działa!Dzięki! 14 wrz. 112011-09-14 17:04:11

  0

@jgilmour Jeśli to działa, możesz zaakceptować odpowiedź, klikając znacznik wyboru obok.To wskazuje przyszłym odwiedzającym, że jest to właściwe rozwiązanie. 29 maj. 122012-05-29 10:33:25