2012-05-11 7 views
0

私はMySQLで派生したクエリには新しく、2つの問題を抱えています。4 INNER JOINと2 LEFT JOINを含むcountとcleanup/streamlineの派生クエリの追加方法

1)t1.dCountを参照して、各optionIdのxcart_images_D.productIdの数をカウントするにはどうすればよいですか?

2)このクエリの派生SELECTを効率化するにはどうすればよいですか? (現在、このクエリを実行するために45秒かかります)

SELECT xp.productid, xp.product, xc.classid, xco.optionid, xco.option_name, xiW.id, xiW.image_path, t1.dCount 
FROM xcart_products xp 
INNER JOIN xcart_variants xv ON xp.productid = xv.productid 
INNER JOIN xcart_variant_items xvi ON xv.variantid = xvi.variantid 
INNER JOIN xcart_class_options xco ON xvi.optionid = xco.optionid 
INNER JOIN xcart_classes xc ON xco.classid = xc.classid AND xc.class = 'COLOR' 
LEFT JOIN xcart_images_W xiW ON xiW.id = xvi.variantid 
LEFT JOIN (
SELECT COUNT(xiD.optionid) as dCount 
    FROM xcart_products xp2 
    INNER JOIN xcart_classes xc2 ON xp2.productid = xc2.productid AND xc2.class = 'Color' 
    INNER JOIN xcart_class_options xco2 ON xc2.classid = xco2.classid 
    LEFT JOIN xcart_images_D xiD ON xiD.optionid = xco2.optionid 
) as t1 ON xiW.id = xvi.variantid 
GROUP BY xco.optionid 
ORDER by xp.product DESC 

ここでの作業回数のバージョンが、派生選択なしです -

SELECT xp.productid, xp.product, xc.classid, xco.optionid, xco.option_name, xiD.image_path, xiD.path_on_server, count(xiD.optionid) as cnt 
    FROM xcart_products xp 
    INNER JOIN xcart_classes xc ON xp.productid = xc.productid AND xc.class = 'Color' 
    INNER JOIN xcart_class_options xco ON xc.classid = xco.classid 
    LEFT JOIN xcart_images_D xiD ON xiD.optionid = xco.optionid 
    GROUP BY xp.product, xco.optionid 
    ORDER by xp.product DESC 

は、それがここで必要なの場合はDBのレイアウトがある -

+ xcart_products 
    - productid* 
    - product 
+ xcart_variants 
    - variantid* 
    - productid (xcart_products.productid) 
+ xcart_variant_items [bridge table] 
    - optionid* 
    - variantid (xcart_variants.variantid) 
+ xcart_classes 
    - classid* 
    - productid (xcart_products.productid) 
    - class 
+ xcart_class_options 
    - optionid* 
    - option_name 
    - classid (xcart_classes.classid) 
+ xcart_images_W 
    - imageid* 
    - id (xcart_variants.variantid) 
    - image_path 
+ xcart_images_D 
    - imageid* [not relational with xcart_images_W.imageid] 
    - id (xcart_products.productid) 
    - optionid (xcart_class_options.optionid) 

* Primary Key 
() relational data 
[] notes 
+0

してください、でサンプル・スキーマを構築[SQL Fiddle](http://sqlfiddle.com)では、スキーマとクエリを確認するのが簡単になります。 – vyegorov

答えて

1

は、ここで私が何を考えて説明し、いくつかのノートを使用して、元のクエリが問題となっています:

SELECT xp.productid, xp.product, xc.classid, xco.optionid, xco.option_name, xiW.id, xiW.image_path, t1.dCount 
FROM xcart_products xp 
INNER JOIN xcart_variants xv ON xp.productid = xv.productid 
INNER JOIN xcart_variant_items xvi ON xv.variantid = xvi.variantid 
INNER JOIN xcart_class_options xco ON xvi.optionid = xco.optionid 
INNER JOIN xcart_classes xc ON xco.classid = xc.classid AND xc.class = 'COLOR' 
LEFT JOIN xcart_images_W xiW ON xiW.id = xvi.variantid 
-- all of the above is pretty standard. 

-- but this part is a little wonky! 
LEFT JOIN (
SELECT COUNT(xiD.optionid) as dCount 
    FROM xcart_products xp2 
    INNER JOIN xcart_classes xc2 ON xp2.productid = xc2.productid AND xc2.class = 'Color' 
    INNER JOIN xcart_class_options xco2 ON xc2.classid = xco2.classid 
    LEFT JOIN xcart_images_D xiD ON xiD.optionid = xco2.optionid 
) as t1 ON xiW.id = xvi.variantid 
-- The inner query here only returns one column, which means it's 
-- *not related* to anything. That's why, outside, you're using an 
-- ON query that has nothing to do with the data inside the table 
-- you're joining! You need to group by in the inner select. 

GROUP BY xco.optionid 
ORDER by xp.product DESC 

ような何か試してみてください:あなたが探している結果に応じて、それはより速く行うために

SELECT xp.productid, xp.product, xc.classid, xco.optionid, xco.option_name, xiW.id, xiW.image_path, t1.dCount 
FROM xcart_products xp 
INNER JOIN xcart_variants xv ON xp.productid = xv.productid 
INNER JOIN xcart_variant_items xvi ON xv.variantid = xvi.variantid 
INNER JOIN xcart_class_options xco ON xvi.optionid = xco.optionid 
INNER JOIN xcart_classes xc ON xco.classid = xc.classid AND xc.class = 'COLOR' 
LEFT JOIN xcart_images_W xiW ON xiW.id = xvi.variantid 
-- Keep the above 

-- but change this one to add a group by. 
LEFT JOIN (
SELECT xco2.optionId as optionid, count(*) as dCount 
    -- this could be cleaned up if the products and class aren't 
    -- really relevant- as it is, it serves only to narrow the set 
    -- of xcart_class_options you'll be looking at/counting for. 
    FROM xcart_products xp2 
    INNER JOIN xcart_classes xc2 ON xp2.productid = xc2.productid AND xc2.class = 'Color' 
    INNER JOIN xcart_class_options xco2 ON xc2.classid = xco2.classid 

    -- bring in the image_ds that match the class_option we are looking 
    -- at 
    LEFT JOIN xcart_images_D xiD ON xiD.optionid = xco2.optionid 

    -- And group by those option_ids. 
    group by xid.optionid 
) as t1 ON xco.optionid = t1.optionid 
-- we join the inner select based on the optionid we were looking at. 

GROUP BY xco.optionid 
ORDER by xp.product DESC 

を、これは意志おそらく仕事、:

SELECT xp.productid, xp.product, xc.classid, xco.optionid, xco.option_name, xiW.id, xiW.image_path, t1.dCount 
FROM xcart_products xp 
INNER JOIN xcart_variants xv ON xp.productid = xv.productid 
INNER JOIN xcart_variant_items xvi ON xv.variantid = xvi.variantid 
INNER JOIN xcart_class_options xco ON xvi.optionid = xco.optionid 
INNER JOIN xcart_classes xc ON xco.classid = xc.classid AND xc.class = 'COLOR' 
LEFT JOIN xcart_images_W xiW ON xiW.id = xvi.variantid 

-- since the optionId is on the thing you're counting, 
-- don't bother with any joins in the nested query and just 
-- count and group. 
LEFT JOIN (
SELECT xiD.optionId as optionid, count(*) as dCount 
    FROM xcart_images_D xiD 
    GROUP BY xiD.optionId 
) as t1 ON xco.optionid = t1.optionid 
-- still join the inner select based on the optionid 

GROUP BY xco.optionid 
ORDER by xp.product DESC