2016-04-12 7 views
0

Ich habe eine harte Zeit um den Kopf, wie die Spalte product_count funktioniert. Es scheint sich irgendwie mit den Aliasen see und e zu referenzieren, die beide auf catalog_category_entity zeigen. InsbesondereMySQL: Spalte aus einer selbst referenzierenden (?) SELECT-Abfrage generiert

WHERE (see.entity_id = e.entity_id) OR (see.path LIKE CONCAT(e.path, '/%')) 

Sowohl see und e sind Aliasnamen für Tabellen catalog_category_entity. Was macht das?

Hier ist die gesamte Abfrage:

SELECT `e`.*, `d_name`.`value` AS `name`, IF(s_name.value_id > 0, s_name.value, d_name.value) AS `name`, `d_is_active`.`value` AS `is_active`, IF(s_is_active.value_id > 0, s_is_active.value, d_is_active.value) AS `is_active`, `d_is_anchor`.`value` AS `is_anchor`, IF(s_is_anchor.value_id > 0, s_is_anchor.value, d_is_anchor.value) AS `is_anchor`, 
    (
     SELECT COUNT(DISTINCT scp.product_id) 
     FROM `catalog_category_entity` AS `see` 
      LEFT JOIN `catalog_category_product` AS `scp` 
       ON see.entity_id=scp.category_id 
     WHERE (see.entity_id = e.entity_id) OR (see.path LIKE CONCAT(e.path, '/%')) 
    ) AS `product_count`, 
    (
     SELECT COUNT(cp.product_id) 
     FROM `catalog_category_product` AS `cp` 
     WHERE (cp.category_id = e.entity_id) 
    ) AS `self_product_count` 
FROM `catalog_category_entity` AS `e` 
    LEFT JOIN `catalog_category_entity_varchar` AS `d_name` ON d_name.entity_id=e.entity_id AND d_name.attribute_id=41 AND d_name.entity_type_id=e.entity_type_id AND d_name.store_id=0 
    LEFT JOIN `catalog_category_entity_varchar` AS `s_name` ON s_name.entity_id=e.entity_id AND s_name.attribute_id=41 AND s_name.entity_type_id=e.entity_type_id AND s_name.store_id=0 
    LEFT JOIN `catalog_category_entity_int` AS `d_is_active` ON d_is_active.entity_id=e.entity_id AND d_is_active.attribute_id=42 AND d_is_active.entity_type_id=e.entity_type_id AND d_is_active.store_id=0 
    LEFT JOIN `catalog_category_entity_int` AS `s_is_active` ON s_is_active.entity_id=e.entity_id AND s_is_active.attribute_id=42 AND s_is_active.entity_type_id=e.entity_type_id AND s_is_active.store_id=0 
    LEFT JOIN `catalog_category_entity_int` AS `d_is_anchor` ON d_is_anchor.entity_id=e.entity_id AND d_is_anchor.attribute_id=51 AND d_is_anchor.entity_type_id=e.entity_type_id AND d_is_anchor.store_id=0 
    LEFT JOIN `catalog_category_entity_int` AS `s_is_anchor` ON s_is_anchor.entity_id=e.entity_id AND s_is_anchor.attribute_id=51 AND s_is_anchor.entity_type_id=e.entity_type_id AND s_is_anchor.store_id=0 
WHERE (`e`.`entity_type_id` = '3') AND (e.entity_id IN('24', '533')) ORDER BY LENGTH(e.path) ASC 
+0

dies ist vielleicht die die meisten selbst verbundenen Abfrage ich je gesehen habe. was versuchst du damit zu erreichen? Ich wette, es gibt viel bessere Möglichkeiten, Sie dorthin zu bringen ... –

+0

Ich gebe die Produktanzahl, unter vielen anderen Dingen, der Kategorien '24' und' 533' zurück. Ich habe das nicht geschrieben, und ich frage mich nur, wie die WHERE-Anweisung der 'product_count'-Spalte funktioniert. – musicliftsme

Antwort

1

Dies ist ein Beispiel einer korrelierten Abfrage, hier die Abfrage Besitzer einen Zustand von außerhalb der Unterabfrage mit einer OR Klausel überprüft.

Im folgenden Unterabfrage gibt es eine distinctcount von production_id, die in beiden Tabellen existieren sollten: catalog_category_entity und catalog_category_product (auch hier gibt es keine Anforderung von LEFT JOIN und eine innere Verknüpfung kann besser arbeiten, wie Sie von der Zählung erhalten rechte Seitentabelle) mit der Bedingung, dass in catalog_category_entity als Haupttabelle OR vorhanden sein sollte Unterabfragepfadfeld sollte mit der Haupttabelle übereinstimmen linker Teil des Pfadfelds bedeutet, dass die Haupttabelle eine Extrastring in der rechten Seite aber den linken Teil enthalten sollte sei gleich.

SELECT COUNT(DISTINCT scp.product_id) 
    FROM `catalog_category_entity` AS `see` 
    LEFT JOIN `catalog_category_product` AS `scp` 
     ON see.entity_id=scp.category_id 
    WHERE (see.entity_id = e.entity_id) 
    OR (see.path LIKE CONCAT(e.path, '/%')) 

Sie Ihre Anfrage vereinfachen kann, wenn die Anforderung klar ist, wie Sie Tabelle verknüpfen catalog_category_entity_int 4mal mit LEFT JOIN, während Sie wie unten verwenden können, nur ein einziges Mal: ​​

LEFT JOIN catalog_category_entity_int` AS `d_is_anchor` 
ON d_is_anchor.entity_id=e.entity_id 
    AND d_is_anchor.attribute_id IN (42,51) 
    AND d_is_anchor.entity_type_id=e.entity_type_id 
    AND d_is_anchor.store_id=0 
+0

Ich bekomme alles andere als den Vergleich zwischen 'see' und' e', weil sie beide Aliase für die Haupttabelle 'catalog_category_entity' sind. Was ist 'see.entity_id = e.entity_id'? – musicliftsme

+0

Ich folgte und las über korrelierte Unterabfragen, und ich verstehe es jetzt. Die 'WHERE' der Unterabfrage (z. B.' see.entity_id = e.entity_id') verwendet die von der äußeren Abfrage zurückgegebenen Daten (d. H. 'E.entity_id' aus dem äußeren' SELECT'. – musicliftsme

Verwandte Themen