2011-01-01 17 views
2

Also habe ich eine Abfrage geschrieben, die eine Bestellung ergreift (dies ist für eine E-Commerce-Typ-Website), und aus dieser Auftrags-ID wird es alle Bestellartikel (ecom_order_items), Druckoptionen (c_print_options) und Bilder (Bilder). Die eoi_p_id ist derzeit ein Fremdschlüssel aus der Bildtabelle.4 Tabelle Abfrage/Join. doppelte Zeilen erhalten

Dies funktioniert gut und die Abfrage ist:

SELECT 
eoi_parentid, eoi_p_id, eoi_po_id, eoi_quantity, 
i_id, i_parentid, 
po_name, po_price 
FROM ecom_order_items, images, c_print_options WHERE eoi_parentid = '1' AND i_id = eoi_p_id AND po_id = eoi_po_id;

Die obige alle Sachen für Ordnung # Ich brauche 1

Nun liegen die Dinge verkomplizieren würde packe ich eine zusätzliche Tabelle hinzugefügt (ecom_products), die muss sich ähnlich wie die Bildtabelle verhalten. Die eoi_p_id kann auch auf einen Fremdschlüssel in dieser Tabelle zeigen. Ich habe ein zusätzliches Feld 'eoi_type' hinzugefügt, das entweder den Wert 'image' oder 'product' hat.

Jetzt können Artikel in der Bestellung aus einer Mischung von Artikeln aus Bildern oder ecom_products bestehen. Was auch immer ich versuche, es endet entweder mit zu vielen Datensätzen, wird nicht wirklich mit eoi_type = 'product' ausgegeben und funktioniert im Allgemeinen nicht. Irgendwelche Ideen, um zu erreichen, wonach ich suche? Kann bei Bedarf SQL-Beispiele bereitstellen?

 
SELECT 
eoi_id, eoi_parentid, eoi_p_id, eoi_po_id, eoi_po_id_2, eoi_quantity, eoi_type, 
i_id, i_parentid, 
po_name, po_price, po_id, 
ep_id 
FROM ecom_order_items, images, c_print_options, ecom_products WHERE eoi_parentid = '9' AND i_id = eoi_p_id AND po_id = eoi_po_id

Die obigen Ausgaben doppelte Zeilen und funktioniert nicht wie erwartet. Gehe ich in die falsche Richtung? Sollte ich separate Fremdschlüsselfelder für die eoi_p_id haben, je nachdem es ein Bild oder ein Produkt ist?

Sollte ich JOINs verwenden?

Hier ist ein mysql der Tabellen in Frage erklären

 
ecom_products 

+-------------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+-------------+--------------+------+-----+---------+----------------+ 
| ep_id  | int(8)  | NO | PRI | NULL | auto_increment | 
| ep_title | varchar(255) | NO |  | NULL |    | 
| ep_link  | text   | NO |  | NULL |    | 
| ep_desc  | text   | NO |  | NULL |    | 
| ep_imgdrop | text   | NO |  | NULL |    | 
| ep_price | decimal(6,2) | NO |  | NULL |    | 
| ep_category | varchar(255) | NO |  | NULL |    | 
| ep_hide  | tinyint(1) | NO |  | 0  |    | 
| ep_featured | tinyint(1) | NO |  | 0  |    | 
+-------------+--------------+------+-----+---------+----------------+ 

ecom_order_items 

+--------------+-------------+------+-----+---------+----------------+ 
| Field  | Type  | Null | Key | Default | Extra   | 
+--------------+-------------+------+-----+---------+----------------+ 
| eoi_id  | int(8)  | NO | PRI | NULL | auto_increment | 
| eoi_parentid | int(8)  | NO |  | NULL |    | 
| eoi_type  | varchar(32) | NO |  | NULL |    | 
| eoi_p_id  | int(8)  | NO |  | NULL |    | 
| eoi_po_id | int(8)  | NO |  | NULL |    | 
| eoi_quantity | int(4)  | NO |  | NULL |    | 
+--------------+-------------+------+-----+---------+----------------+ 

c_print_options 

+------------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+------------+--------------+------+-----+---------+----------------+ 
| po_id  | int(8)  | NO | PRI | NULL | auto_increment | 
| po_name | varchar(255) | NO |  | NULL |    | 
| po_price | decimal(6,2) | NO |  | NULL |    | 
+------------+--------------+------+-----+---------+----------------+ 

images 

+--------------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+--------------+--------------+------+-----+---------+----------------+ 
| i_id   | int(8)  | NO | PRI | NULL | auto_increment | 
| i_filename | varchar(255) | NO |  | NULL |    | 
| i_data  | longtext  | NO |  | NULL |    | 
| i_parentid | int(8)  | NO |  | NULL |    | 
+--------------+--------------+------+-----+---------+----------------+ 

Antwort

1

So würde ich die erste Abfrage schreiben. Ich bevorzuge die Verwendung von Joins.

Für Ihre zweite Abfrage würde ich eine UNION für zwei Abfragen verwenden, eine für Bilder und eine für Produkte.

SELECT eoi_id, eoi_parentid, eoi_p_id, eoi_po_id, eoi_po_id_2, eoi_quantity, eoi_type, i_id, i_parentid, po_name, po_price, po_id, ep_id 
FROM ecom_order_items 
INNER JOIN images 
    ON i_id = eoi_p_id 
INNER JOIN c_print_options 
    ON po_id = eoi_po_id 
WHERE eoi_type = 'image' AND i_id = eoi_p_id --Image conditions 
    AND eoi_parentid = '9' 
    AND po_id = eoi_po_id 

UNION 

SELECT eoi_id, eoi_parentid, eoi_p_id, eoi_po_id, eoi_po_id_2, eoi_quantity, eoi_type, i_id, i_parentid, po_name, po_price, po_id, ep_id 
FROM ecom_order_items 
INNER JOIN images 
    ON i_id = eoi_p_id 
INNER JOIN c_print_options 
    ON po_id = eoi_po_id 
WHERE eoi_type = 'product' AND ep_id = eoi_p_id -- Product conditions 
    AND eoi_parentid = '9' 
    AND po_id = eoi_po_id 
+0

Diese Art von Arbeiten, jedoch der untere Teil der Union gibt 0 Zeilen zurück. Dies liegt daran, wenn es ein Produkt ist, hat es keine Druckoptionen, und das Entfernen von der unteren Abfrage hat Auswirkungen auf die oberste Abfrage, zB müssen die ausgewählten Spalten übereinstimmen – Horse

+0

Yay! mit ein bisschen Bastelei habe ich es funktioniert, brauchte eine linke Join auf die Druckoptionen Bit in der zweiten Abfrage. Vielen Dank! – Horse

+0

Froh, es hat funktioniert.Ich saß nur auf der Couch und erkannte, dass die Spalten in der Auswahlliste möglicherweise nicht richtig zusammenpassen, froh, dass Sie das bemerkt haben. In einem anderen Fall haben Sie gefragt: "Sollte ich separate Fremdschlüsselfelder haben" und nachdem ich darüber nachgedacht habe, denke ich, dass Sie das sollten. Bilder und Produkte scheinen nichts gemeinsam zu haben. Warum die Beziehung zu einem Typ-Feld komplizieren, wenn Sie nur zwei FKs haben könnten? – mikesigs

2

Sie verpassen eine Bedingung entweder in der WHERE für ecom_products beitreten oder FROM-Klausel. Dies ist, wie wäre es

SELECT 
    eoi_id, 
    eoi_parentid, 
    eoi_p_id, 
    eoi_po_id, 
    eoi_po_id_2, 
    eoi_quantity, 
    eoi_type, 
    i_id, 
    i_parentid, 
    po_name, 
    po_price, 
    po_id, 
    ep_id 
FROM 
    ecom_order_items, 
    LEFT JOIN images 
    ON i_id = eoi_p_id 
    LEFT JOIN c_print_options 
    ON po_id = eoi_po_id 
    INNER JOIN ecom_products 
    ON eoi_p_id = ep_id 
WHERE 
    eoi_parentid = '9' 

ANSI 92 Joins sind bevorzugt, und es ist ein wenig klarer, was eine Verknüpfung und was Filterung ANSI-92 verbindet erfolgen. Das heißt, Sie könnten einfach AND eoi_p_id = ep_id zu Ihrer Where-Klausel hinzufügen.

+0

Es gibt das zusätzliche Problem des doppelten Fremdschlüssels. Sie müssen dies in Ihren ON-Klauseln berücksichtigen oder eine UNION verwenden, wie ich es getan habe. – mikesigs

+0

Dies gibt 0 Zeilen zurück, was vermutlich auf den gleichen Grund zurückzuführen ist wie der folgende Post von whatispunk. Müssen die Druckoptionen möglicherweise keine Ergebnisse haben, also vielleicht einen linken Join? – Horse

+0

Wenn es ein Potenzial für keine Druckoptionen gibt, machen Sie es einfach zu einem linken Join Eine UNION ist übertrieben –