【问题标题】:How to count values conditionally in SQL如何在 SQL 中有条件地计算值
【发布时间】:2016-08-13 02:48:21
【问题描述】:

我有一个实体属性值的索引表,如下所示: +-----------+--------------+----------+-------+ | entity_id | attribute_id | store_id | value | +-----------+--------------+----------+-------+ | 38 | 190 | 1 | 22 | | 38 | 190 | 1 | 23 | | 39 | 190 | 1 | 22 | | 39 | 190 | 1 | 23 | | 39 | 190 | 1 | 42 | | 40 | 190 | 1 | 22 | | 41 | 190 | 1 | 54 | | 42 | 190 | 1 | 54 | | 43 | 190 | 1 | 22 | | 44 | 190 | 1 | 22 | | 45 | 190 | 1 | 54 | +-----------+--------------+----------+-------+

如您所见,单个实体可以为单个属性具有多个值(entity_id38 具有 values 22,23)并且这些值对于每个实体不是唯一的(entity_id38,39 两者共享value 22)。

要解决的第一个问题是获取每个值的不同实体的数量;这很容易实现:

SELECT value, COUNT(entity_id) AS count
FROM catalog_product_index_eav
WHERE attribute_id=190
GROUP BY value;

导致: +-------+-------+ | value | count | +-------+-------+ | 22 | 5 | | 23 | 2 | | 42 | 1 | | 54 | 3 | +-------+-------+

我的问题是如何在此计数中嵌套 OR 条件,即:对于某些 特定 值 Y,对于每个值 X,计算具有值 X 或 Y 的实体的数量。

我想在单个查询中执行此操作。例如,对于attribute_id 190 和value 23,上述示例的输出应为: +-------+-------+ | value | count | +-------+-------+ | 22 | 5 | # all entities with value 22 happen to have 23 as well | 23 | 2 | that is, one is a subset of the other | 42 | 2 | # intersection is nonempty | 54 | 5 | # sets are disjoint +-------+-------+

【问题讨论】:

  • 除了只选择特定值之外,您想运行相同的查询吗?
  • 没有。考虑导致第一个 [value, count] 表的第一个查询。我想找到一个类似的查询,它会导致上面的第二个 [value, count] 表。它仍然选择所有值,但它有条件地计算 entity_id 的值为 x OR y,而不是计算 entity_id 的值为 x。
  • 所以您想要为第一个结果表中的每个值创建一个单独的结果集?

标签: mysql sql magento count group-by


【解决方案1】:
select c1.value, 
( SELECT COUNT(DISTINCT entity_id) as count 
  FROM catalog_product_index_eav 
  where attribute_id=81 
  and (value=c1.value || value=7) ) as count 
FROM catalog_product_index_eav c1 
WHERE attribute_id=81 
GROUP BY c1.value

【讨论】:

  • 谢谢,此查询提供了所需的结果。如果有人能提出更有效的查询,我将更改接受的答案。谢谢!
  • 我不接受这个答案,因为计数不尊重外部选择中的 WHERE 参数。这对我的用例来说是必要的。
【解决方案2】:

尝试使用

Select C.value, max(C.count) from (
SELECT A.value, (Select COUNT(B.entity_id) from FROM catalog_product_index_eav B
WHERE B.attribute_id=A.attribute_id and (B.value=A.value or B.value=23)) AS count
FROM catalog_product_index_eav A
WHERE A.attribute_id=190) C group by C.value

【讨论】:

  • 抱歉,这不是正确的逻辑。使用这个查询,我得到一个 ['value' => 22, 'count' => 7] 对。请参阅原始问题,查询应该只计算唯一实体。
【解决方案3】:

如果满足您的输出,它会在单个查询中为您提供两个结果。

SELECT i.value AS [value], COUNT(i.entity_id) AS [count], 
(SELECT COUNT(b.entity_id) tot FROM catalog_product_index_eav b
        WHERE b.entity_id IN (SELECT v.entity_id FROM 
        catalog_product_index_eav v WHERE v.VALUE = i.value)) AS [total_count]
FROM catalog_product_index_eav i
WHERE i.attribute_id=190
GROUP BY i.value

【讨论】:

  • 这里好像有语法错误,我不能按原样运行这个SQL。我的版本是:Ver 15.1 Distrib 10.1.16-MariaDB, for Linux (x86_64) using readline 5.1
  • 在 SQL 2012 中运行良好,能否请您发布简短的错误消息
  • ERROR 1064 (42000): 你的 SQL 语法有错误;检查与您的 MariaDB 服务器版本相对应的手册,以在第 3 行的 OUTER APPLY(SELECT COUNT(entity_id) tot FROM catalog_product_index_eav 附近使用正确的语法
  • 你能检查一下上面编辑过的查询吗,没有任何改变,因为我没有任何改变我只添加了别名并将列括在方括号中,因为有时它在其他版本中会出错,并且在数据库中。
猜你喜欢
  • 2021-06-21
  • 2011-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-15
  • 2017-08-15
  • 2023-02-09
相关资源
最近更新 更多