繁体   English   中英

SQL查询以查找常用属性

[英]SQL Query to find common attributes

我有带有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。

您可以使用有条件的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

如果您希望ProductID具有其他属性,则可以使用>= 2

一种替代方法是使用传统的“数据透视查询”,并将其视为“派生表”,然后您将获得大小/重量/颜色为行,从而使其易于过滤。

SQL小提琴

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'

结果

| ProductID | Size | Color | Weight |
|-----------|------|-------|--------|
|       100 |  Big |   Red |  Heavy |
|       300 |  Big | Green |  Heavy |

有两种不同的方法可以做到这一点。 这是使用条件聚合的一种:

select productid
from yourtable
group by productid
having max(case when attribute = 'Size' then value end) = 'Big'
   and max(case when attribute = 'Weight' then value end) = 'Heavy'

相信您想要成对的产品。 另外,我并没有在任何地方对值进行硬编码。 如果您需要更改属性集,只需修改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

我有点倾向于认为像Felix这样的答案就是您想要的。

如果只需要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子句,以避免对表/索引进行完整扫描。 根据表的大小和数据,这可能是一个巨大的优势,因为可以进行早期过滤。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM