我试图查询我的产品表,以便我的查询返回某个价格范围内的产品集-产品具有许多变体,并且变体属于产品。我有以下正在运行的查询,但是它非常慢-查询需要1.66秒。
SELECT colortags.tag, products.*, (SELECT variants.price FROM variants WHERE variants.product_id = products.product_id LIMIT 1) price, collects.position
FROM products
INNER JOIN wp_wps_collects collects
ON products.product_id = collects.product_id
AND collects.collection_id = 123456788
INNER JOIN wp_wps_tags colortags
ON colortags.product_id = collects.product_id
AND (colortags.tag = 'black' OR colortags.tag = 'nav')
INNER JOIN wp_wps_tags styletags
ON styletags.product_id = collects.product_id
AND (styletags.tag = 'purses')
WHERE (SELECT variants.price FROM variants WHERE variants.product_id = products.product_id AND variants.price >= 200 AND variants.price < 300 LIMIT 1) > 0
AND (SELECT variants.price FROM variants WHERE variants.product_id = products.product_id AND variants.price >= 200 AND variants.price < 300 LIMIT 1) <> 0
在WHERE
语句中,我尝试仅在SELECT语句中检查由子查询创建的price
值,但是MYSQL告诉我price
未定义。这是SQL:
SELECT colortags.tag, products.*, (SELECT variants.price FROM wp_wps_variants variants WHERE variants.product_id = products.product_id LIMIT 1) price, collects.position
FROM wp_wps_products products
INNER JOIN wp_wps_collects collects
ON products.product_id = collects.product_id
AND collects.collection_id = 98515058801
INNER JOIN wp_wps_tags colortags
ON colortags.product_id = collects.product_id
AND (colortags.tag = 'color:generic-black' OR colortags.tag = 'color:navy')
INNER JOIN wp_wps_tags styletags
ON styletags.product_id = collects.product_id
AND (styletags.tag = 'style:totes')
WHERE price >= 200
AND price < 300
这是我从上面的SQL中收到的错误消息:
“ where子句”中的未知列“ price”
我还尝试在variants
表上使用一系列联接,但是随后我得到了重复的产品。这是SQL
SELECT colortags.tag, products.*, (SELECT variants.price FROM variants WHERE variants.product_id = products.product_id LIMIT 1) price, collects.position
FROM products
INNER JOIN collects
ON products.product_id = collects.product_id
AND collects.collection_id = 1234566
INNER JOIN colortags
ON colortags.product_id = collects.product_id
AND (colortags.tag = 'black' OR colortags.tag = 'navy')
INNER JOIN styletags
ON styletags.product_id = collects.product_id
AND (styletags.tag = 'purses')
INNER JOIN variants
ON variants.product_id = products.product_id
AND variants.price >= 200
AND variants.price < 300
AND variants.price > 0
AND variants.price <> 0
我想要的是从第一个SQL语句获得的查询结果,而不会影响性能。我想认为我可以在变量表上用INNER JOIN
编写SQL,以过滤出不正确价格的变量,而又不会得到重复的产品,但是我无法确定该怎么做。
有人知道我如何在这里编写SQL,使我能够查询一定价格范围内的产品,而又不会退回重复的产品,而不会严重影响性能?
答案 0 :(得分:1)
如果将查询封装在另一个查询中,则可以在price
子句中使用where
SELECT * from (
SELECT colortags.tag, products.*, (SELECT variants.price FROM variants WHERE variants.product_id = products.product_id LIMIT 1) price, collects.position
FROM products
INNER JOIN wp_wps_collects collects
ON products.product_id = collects.product_id
AND collects.collection_id = 123456788
INNER JOIN wp_wps_tags colortags
ON colortags.product_id = collects.product_id
AND (colortags.tag = 'black' OR colortags.tag = 'nav')
INNER JOIN wp_wps_tags styletags
ON styletags.product_id = collects.product_id
AND (styletags.tag = 'purses')
WHERE (SELECT variants.price FROM variants WHERE variants.product_id = products.product_id AND variants.price >= 200 AND variants.price < 300 LIMIT 1) > 0
) t
WHERE t.price >= 200 and t.price < 300
答案 1 :(得分:1)
您正在执行半联接,这意味着您想进行联接,但是即使有多个匹配项,也只需要一行结果。
执行此操作的一种方法是联接到派生表,该表在子查询中使用GROUP BY将每个product_id的变体减少为一行。
SELECT colortags.tag, products.*, prices.price, collects.position
FROM products
INNER JOIN wp_wps_collects collects
ON products.product_id = collects.product_id
AND collects.collection_id = 123456788
INNER JOIN wp_wps_tags colortags
ON colortags.product_id = collects.product_id
AND (colortags.tag = 'black' OR colortags.tag = 'nav')
INNER JOIN wp_wps_tags styletags
ON styletags.product_id = collects.product_id
AND (styletags.tag = 'purses')
INNER JOIN (
SELECT v.product_id, MIN(v.price) AS price FROM variants v
INNER JOIN wp_wps_collects c ON v.product_id = c.product_id
WHERE c.collection_id = 123456788
GROUP BY product_id ORDER BY NULL
) prices
ON products.product_id = prices.product_id
我假设您会对每种产品的最低价格感兴趣。您也可以在派生表中使用MAX()
。
我必须将联接复制到wp_wps_collects
,因此派生表将限于与您要查询的集合相关的产品。否则,如果您有数百万种产品,则派生表将变得很大,以至于将产生另一个性能问题。