MYSQL 查询变体价格范围内没有重复的产品
MYSQL query on products within variant price range without duplicates
我正在尝试查询我的产品 table,以便我查询 returns 某个变体价格范围内的产品集 -- 产品有很多变体,变体属于产品。我有以下正在运行的查询,但它非常慢 -- 查询需要 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:
得到的错误消息
Unknown column 'price' in 'where clause'
我也曾尝试在 variants
table 上使用一系列连接,但随后返回了重复的产品。这是 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 语句获得的没有性能影响的查询结果。我想我可以在变体 table 上写 SQL 和 INNER JOIN
来过滤掉不正确价格的变体而不会得到重复的产品,但我无法确定如何。
有谁知道我如何在此处编写 SQL,这样我就可以在特定变体价格范围内查询产品,而不会返回重复产品并且不会严重影响性能?
如果将查询封装在另一个查询中,则可以在 where
子句中使用 price
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
你正在做一个半连接,这意味着你想做一个连接,但你只想要一行结果,即使有多个匹配。
执行此操作的一种方法是连接到派生的 table,它在子查询中使用 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
我以为您会对每件产品的最低价格感兴趣。您也可以在派生的 table.
中使用 MAX()
我不得不将连接复制到 wp_wps_collects
,因此派生的 table 将仅限于与您正在查询的集合相关的产品。否则,如果您有数百万个产品,派生的 table 会变得如此之大,以至于会产生不同的性能问题。
我正在尝试查询我的产品 table,以便我查询 returns 某个变体价格范围内的产品集 -- 产品有很多变体,变体属于产品。我有以下正在运行的查询,但它非常慢 -- 查询需要 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:
得到的错误消息Unknown column 'price' in 'where clause'
我也曾尝试在 variants
table 上使用一系列连接,但随后返回了重复的产品。这是 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 语句获得的没有性能影响的查询结果。我想我可以在变体 table 上写 SQL 和 INNER JOIN
来过滤掉不正确价格的变体而不会得到重复的产品,但我无法确定如何。
有谁知道我如何在此处编写 SQL,这样我就可以在特定变体价格范围内查询产品,而不会返回重复产品并且不会严重影响性能?
如果将查询封装在另一个查询中,则可以在 where
子句中使用 price
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
你正在做一个半连接,这意味着你想做一个连接,但你只想要一行结果,即使有多个匹配。
执行此操作的一种方法是连接到派生的 table,它在子查询中使用 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
我以为您会对每件产品的最低价格感兴趣。您也可以在派生的 table.
中使用MAX()
我不得不将连接复制到 wp_wps_collects
,因此派生的 table 将仅限于与您正在查询的集合相关的产品。否则,如果您有数百万个产品,派生的 table 会变得如此之大,以至于会产生不同的性能问题。