我有一个由ERP生成的3列的SQL表。
+-----------+-----------+------------+
| ProductID | Attribute | Value |
+-----------+-----------+------------+
| 100 | Size | Big |
| 100 | Color | Red |
| 100 | Weight | Heavy |
| 200 | Size | Small |
| 200 | Color | Red |
| 200 | Weight | Light |
| 300 | Size | Big |
| 300 | Color | Green |
| 300 | Weight | Heavy |
+-----------+-----------+------------+
我想查询表以查找具有匹配属性的产品。例如
SELECT * FROM Table
WHERE Attribute ='Size' AND Value = 'Big' AND Attribute ='Weight' AND Value = 'Heavy'
返回产品100和300.
答案 0 :(得分:1)
您可以使用条件SUM
:
SELECT ProductID
FROM tbl
GROUP BY ProductID
HAVING
SUM(
CASE
WHEN Attribute = 'Size' AND Value = 'BIG' THEN 1
WHEN Attribute = 'Weight' AND Value = 'Heavy' THEN 1
ELSE 0
END
) = 2
如果您希望>= 2
具有其他属性,则可以使用ProductID
。
答案 1 :(得分:1)
另一种方法是使用传统的“数据透视查询”并将其视为“派生表”,然后您将获得尺寸/重量/颜色作为行,以便过滤。
MySQL 5.6架构设置:
CREATE TABLE ERPout
(`ProductID` int, `Attribute` varchar(6), `Value` varchar(5))
;
INSERT INTO ERPout
(`ProductID`, `Attribute`, `Value`)
VALUES
(100, 'Size', 'Big'),
(100, 'Color', 'Red'),
(100, 'Weight', 'Heavy'),
(200, 'Size', 'Small'),
(200, 'Color', 'Red'),
(200, 'Weight', 'Light'),
(300, 'Size', 'Big'),
(300, 'Color', 'Green'),
(300, 'Weight', 'Heavy')
;
查询1 :
SELECT
ProductID
, Size
, Color
, Weight
FROM (
SELECT
ProductID
, MAX(CASE WHEN Attribute = 'Size' THEN VALUE END) AS Size
, MAX(CASE WHEN Attribute = 'Color' THEN VALUE END) AS Color
, MAX(CASE WHEN Attribute = 'Weight' THEN VALUE END) AS Weight
FROM ERPout
GROUP BY
ProductID
) p
WHERE Size = 'Big'
AND Weight = 'Heavy'
<强> Results 强>:
| ProductID | Size | Color | Weight |
|-----------|------|-------|--------|
| 100 | Big | Red | Heavy |
| 300 | Big | Green | Heavy |
答案 2 :(得分:0)
答案 3 :(得分:0)
我相信你想要成对的产品。此外,我不是在任何地方对这些值进行硬编码。如果您需要更改属性集,只需修改having
子句。
select t1.ProductID, t2.ProductID
from
T t1 inner join T t2
on t2.ProductID > t1.ProductID
and t2.Attribute = t1.Attribute and t2.Value = t1.Value
group by
t1.ProductID, t2.ProductID
having
count(case when t1.Attribute = 'Size' then 1 end) = 1
and count(case when t1.Attribute = 'Weight' then 1 end) = 1
我有点倾向于认为像费利克斯这样的答案就是你想要的。
答案 4 :(得分:0)
如果您只需要 ProductID ,这将是一个简短而有效的解决方案:
SELECT ProductID
FROM product_info
WHERE Attribute ='Size' AND Value = 'Big'
OR Attribute ='Weight' AND Value = 'Heavy'
GROUP BY ProductID
HAVING COUNT(ProductID) = 2
如果您需要一行中的所有属性并且已在( ProductID,Attribute )上定义了(唯一/主要)键,则可能需要使用如下查询:
SELECT size.ProductID, size.Value Size, color.Value Color, weight.Value Weight
FROM product_info size
JOIN product_info weight USING(ProductID)
LEFT JOIN product_info color
ON color.ProductID = size.ProductID
AND color.Attribute = 'Color'
WHERE size.Attribute = 'Size' AND size.Value = 'Big'
AND weight.Attribute = 'Weight' AND weight.Value = 'Heavy'
如果您另外在 Value 上定义索引,性能会更好。
两个查询都使用WHERE子句来避免完整的表/索引扫描。根据表格大小和数据,这可能是一个巨大的优势,因为早期过滤。