MySQL: zusätzliches LEFT JOIN in komplexes Query integrieren

tklustig

Erfahrenes Mitglied
Hallo, folgendes Query liefert mir alle Masterprodukte samt zugehöriger Variantenprodukte:
SQL:
SET @languageID='2fbb5fe2e29a4d70aa5854ce7ce3e20b';
SELECT master.id,master.product_number, MIN(master.name) AS masterBez,
variant.id,variant.product_number, MIN(variant.name) AS variantBez
FROM
(SELECT product.id,product.product_number, prodTrans.name, product.parent_id
FROM product
   LEFT JOIN product_translation AS prodTrans
ON product.id=prodTrans.Product_id
AND prodTrans.language_id=UNHEX(@languageID)
) As master
INNER JOIN
(SELECT product.id,product.product_number, prodTrans.name, product.parent_id
FROM product
LEFT JOIN product_translation AS prodTrans
ON product.id=prodTrans.product_id
AND prodTrans.language_id=UNHEX(@languageID)
) AS variant
ON variant.parent_id=master.id
GROUP BY master.id, variant.id;

Das Query ist für meine SQL Kenntnisse zu komplex. Ich benötige 3 zusätzliche LEFT JOIN wie folgt um den Bezug von der Tabelle product zu der erwünschten Attributbezeichnung property_group_option_translation.name im ersten SELECT Block herzustellen, aber wo integriere ich diese?
SQL:
LEFT JOIN product_property ON product.id = product_property.product_id
LEFT JOIN property_group_option ON property_group_option.id = product_property.property_group_option_id
LEFT JOIN property_group_option_translation ON property_group_option_translation.property_group_option_id = property_group_option.id

Folgendes Query liefert mir also alle Attributbezeichnungen. Diese Ausgabe gilt es jetzt in obiges Query zu integrieren.
SQL:
SELECT product.id AS ProductID, property_group_option_translation.name AS AttributBez
FROM product
LEFT JOIN product_property ON product.id = product_property.product_id
LEFT JOIN property_group_option ON property_group_option.id = product_property.property_group_option_id
LEFT JOIN property_group_option_translation ON property_group_option_translation.property_group_option_id = property_group_option.id
 
Zuletzt bearbeitet:
Lösung
Ersetze trans.pt_name, p.name AS p_name, durch trans.pt_name AS p_name,

Es geht ohne With, wird aber noch viel komplexer. Dein Ursprungssql ist schon fast nicht mehr lesabr, weil alles in einem grossen Kneuel ist. Mit With kann man die Einzelteile vorbereiten und dann zusammensetzen.

Aber bisste sehr, wenn du das ohne WITH besser lesen kannst - ich kann es nicht
SQL:
SELECT master.id AS master_id, master.product_number AS master_product_number, MIN(master.p_name) AS masterBez,
   variant.id AS variant_id, variant.product_number AS variant_product_number, MIN(variant.p_name) AS variantBez,
   master.AttributBez as masterAttrBez, variant.AttributBez as variantAttrBez
FROM (
      SELECT p.id, p.product_number, trans.pt_name...
Brauchstd du das für den Master oder für Variant?

Das kleine Select kannst du kürzen. Du brauchst da das product noch nicht. Erst nachher beim Einbau
SQL:
SELECT pp.product_id AS ProductID, pgot.name AS AttributBez
FROM  product_property pp
LEFT JOIN property_group_option pgo ON pgo.id = pp.property_group_option_id
LEFT JOIN property_group_option_translation pgot ON pgot.property_group_option_id = pgo.id
 
Ich brauche es für beides! Sowohl für Master als auch für Variant! Dein Query liefert mir im übrigen die NULL Werte nicht mit. Nicht weiters tragisch in diesem Kontext, aber die Kürzung ist damit nicht identisch!
 
Ich sehe grad, die Tabelle property_group_option kannst du überspringen.
Das ganze noch in die besser lesbare Schreibweise mit WITH ergibt ungefär sowas.
(hier noch die Erklärung zu With — komplexe Abfragen strukturieren)

SQL:
SET @languageID='2fbb5fe2e29a4d70aa5854ce7ce3e20b';

-- Atribut Bezeichnungen
with attr as (
   SELECT pp.product_id, pgot.name AS AttributBez
   FROM  product_property pp    
      LEFT JOIN property_group_option_translation pgot ON pgot.property_group_option_id = pp.property_group_option_id
),
-- Transationen
-- Name unbenennen. Niemals eine Spalte mit 'name' benamsen
trans as (
   select pt.name AS pt_name, pt.Product_id
   from product_translation pt
   where pt.language_id = UNHEX(@languageID)
),
-- Daten. Master & Variants
-- Produkt um Attribut und Translation ergänzen
p_data as (
   SELECT p.id, p.product_number, trans.pt_name, p.name AS p_name, p.parent_id, attr.AttributBez
   FROM product p
      LEFT JOIN trans ON p.id  = trans.Product_id
      LEFT JOIN attr ON p.id = attr.product_id
)

-- Master und Variant (beides die gleiche Quelle) kombinieren
SELECT master.id AS master_id, master.product_number AS master_product_number, MIN(master.p_name) AS masterBez,
   variant.id AS variant_id, variant.product_number AS variant_product_number, MIN(variant.p_name) AS variantBez,
   master.AttributBez as masterAttrBez, variant.AttributBez as variantAttrBez
FROM p_data as master
   INNER JOIN p_data as variant ON variant.parent_id = master.id
GROUP BY master.id, variant.id, master.product_number, variant.product_number, master.AttributBez, variant.AttributBez;
 
Viel zu komplex, um da noch durchzuchecken: Error: Unknown column p.name in field list. Geht das nicht auch ohne with? Das Feld p.name AS p_name wird nicht erkannt bei
-- Daten. Master & Variants -- Produkt um Attribut und Translation ergänzen
 
Zuletzt bearbeitet:
Ersetze trans.pt_name, p.name AS p_name, durch trans.pt_name AS p_name,

Es geht ohne With, wird aber noch viel komplexer. Dein Ursprungssql ist schon fast nicht mehr lesabr, weil alles in einem grossen Kneuel ist. Mit With kann man die Einzelteile vorbereiten und dann zusammensetzen.

Aber bisste sehr, wenn du das ohne WITH besser lesen kannst - ich kann es nicht
SQL:
SELECT master.id AS master_id, master.product_number AS master_product_number, MIN(master.p_name) AS masterBez,
   variant.id AS variant_id, variant.product_number AS variant_product_number, MIN(variant.p_name) AS variantBez,
   master.AttributBez as masterAttrBez, variant.AttributBez as variantAttrBez
FROM (
      SELECT p.id, p.product_number, trans.pt_name AS p_name, p.parent_id, attr.AttributBez
      FROM product p
         LEFT JOIN (
            select pt.name AS pt_name, pt.Product_id 
            from product_translation pt
            where pt.language_id = UNHEX(@languageID)
         ) as trans ON p.id  = trans.Product_id
         LEFT JOIN (
            SELECT pp.product_id, pgot.name AS AttributBez
            FROM  product_property pp      
            LEFT JOIN property_group_option_translation pgot ON pgot.property_group_option_id = pp.property_group_option_id
         ) as attr ON p.id = attr.product_id
   ) as master
   INNER JOIN (
      SELECT p.id, p.product_number, trans.pt_name AS p_name, p.parent_id, attr.AttributBez
      FROM product p
         LEFT JOIN (
            select pt.name AS pt_name, pt.Product_id 
            from product_translation pt
            where pt.language_id = UNHEX(@languageID)
         ) as trans ON p.id  = trans.Product_id
         LEFT JOIN (
            SELECT pp.product_id, pgot.name AS AttributBez
            FROM  product_property pp      
            LEFT JOIN property_group_option_translation pgot ON pgot.property_group_option_id = pp.property_group_option_id
         ) as attr ON p.id = attr.product_id
   ) as variant ON variant.parent_id = master.id
GROUP BY master.id, variant.id, master.product_number, variant.product_number, master.AttributBez, variant.AttributBez;
 
Zuletzt bearbeitet:
Lösung
Teste ich morgen. Falls es Dich interessiert: Das "Grundgerüst" der Datenbank ist öffentlich downloadbar und nennt sich Shopware6. Würde die darauf aufbauende Datenbank ja zum Download anbieten, aber das wären mehr als 4 GByte an Daten, da sich >10^6 Records in der Tabelle product befinden. Ob eine No SQL Datenbank nicht performanter wäre steht auf einem anderen Blatt.
 
Zuletzt bearbeitet:
Explizit vielen Dank an Yaslaw alias Alter Rempler. Der Response dauert zwar eine gefühlte Ewigkeit, aber Dein Query passt. Alle Achtung! Ein solches Query formulieren zu können ohne die Datenbank zur Verfügung zu haben, ist eine beachtliche Leistung. Deklariere diesen Thread heute Abend als gelöst. Hier nochmals das Query, allerdings mit WITH:
SQL:
SET @languageID='2fbb5fe2e29a4d70aa5854ce7ce3e20b';
-- Atribut Bezeichnungen
WITH attributes AS (
SELECT product_property.product_id, property_group_option_translation.name AS AttributBez
 FROM  product_property
LEFT JOIN property_group_option_translation ON property_group_option_translation.property_group_option_id = product_property.property_group_option_id
),
-- Spalte name in der Tabelle product_translation umbenennen
     renameTransTable AS (
SELECT product_translation.name AS pt_name, product_translation.product_id
         FROM product_translation
WHERE product_translation.language_id = UNHEX(@languageID)
),
-- Daten. Master & Variants
-- Produkt um Attribut und Translation Tabelle ergänzen
     p_data as (
SELECT product.id, product.product_number, renameTransTable.pt_name AS p_name, product.parent_id, attributes.AttributBez
 FROM product
LEFT JOIN renameTransTable ON product.id  = renameTransTable.product_id
                  LEFT JOIN attributes ON product.id = attributes.product_id
     )

-- Master und Variant (beides die gleiche Quelle) kombinieren
SELECT master.id AS master_id, master.product_number AS master_product_number, MIN(master.p_name) AS masterBez,
       variant.id AS variant_id, variant.product_number AS variant_product_number, MIN(variant.p_name) AS variantBez,
       master.AttributBez AS masterAttrBez, variant.AttributBez as variantAttrBez
FROM p_data AS master
         INNER JOIN p_data AS variant ON variant.parent_id = master.id
GROUP BY master.id, variant.id, master.product_number, variant.product_number, master.AttributBez, variant.AttributBez;
 
Zuletzt bearbeitet:
Zurück