繁体   English   中英

理论 - 计算不同计数的最快方法

[英]Theoretical - Fastest way to compute different counts

我想知道有经验的 sql 用户如何在不同条件下计算大量计数。 我有一个表 [population] 和一个表 [sql_rules]。

我的 [population] 表看起来像这样,有大约 170 万行和大约 30 列。

眼睛的颜色 发色 年龄 起源 收入 ...
蓝色的 棕色的 36 我们 40000 ...
绿色 黄色 17 英国 60000 ...
棕色的 黑色的 42 20000 ...
黑色的 黑色的 28 丹麦 80000 ...
... ... ... ... ... ...

我的 [sql_rules] 表看起来像这样,有约 800 行,最多 8 条规则(平均约 5 条):

行号 规则1 规则_2 规则_3 规则_4 ...
1 hair_color = '棕色' 年龄 < 27 原产地 IN ('US', 'UK') 收入 >= 40000 ...
2 hair_color = '黑色' 原产地 IN ('DK', 'FR') 年龄 < 10 收入 >= 40000 ...
3 hair_color = '黄色' 原点 IN ('TH', 'PE') 年龄 > 34
4 hair_color = '黑色' 年龄 > 99 原产地 IN ('US', 'UK') 收入 >= 40000 ...
5 年龄 < 27 收入 >= 100000
... ... ... ... ... ...

我需要做的基本上是逐行“迭代”并在一个接一个地应用规则时计算计数,以便按我的 sql_rules 表的单元格获得一个“计数”。 基本上,由于很难用语言来解释,这里是我想获得的计数:

行号 规则1 规则_2 规则_3 规则_4 ...
1 SELECT COUNT(*) FROM 人口 WHERE hair_color = 'brown' 从人口中选择 COUNT(*),其中 hair_color = 'brown' AND age < 27 SELECT COUNT(*) FROM 人口 WHERE hair_color = 'brown' AND age < 27 AND origin in ('US', 'UK') 从人口中选择 COUNT(*),其中 hair_color = 'brown' AND age < 27 AND origin in ('US', 'UK') AND income >= 40000 ...
2 SELECT COUNT(*) FROM 人口 WHERE hair_color = 'black' SELECT COUNT(*) FROM population WHERE hair_color = 'black' AND origin IN ('DK', 'FR') SELECT COUNT(*) FROM 人口 WHERE hair_color = 'black' AND origin IN ('DK', 'FR') AND age < 10 SELECT COUNT(*) FROM 人口 WHERE hair_color = 'black' AND origin IN ('DK', 'FR') AND age < 10 AND income >= 40000 ...
3 ... ... ... ... ...
5 从年龄 < 27 岁的人群中选择 COUNT(*) 从年龄 < 27 岁且收入 >= 100000 的人口中选择计数(*)
... ... ... ... ... ...

我现在所做的是使用我的表 [sql_rules] 创建所有 SQL '查询'。 由于它们在第三列或第四列之前通常是相似的,因此我避免多次重新计算相同的计数,并在已经计算特定“计数”的情况下取值。

有人能想到最快的方法吗? 我的解决方案运行良好,但我想不出更快的方法来做到这一点。 我能够使用 sql、Python、R。

编辑:理想情况下,为了“兴趣”,我正在寻找一些可能会加速该过程的好主意。 以下是一些想法的例子,这些想法并不是很好,而是为了举例说明我在寻找什么:

  1. 使用 sql_rules 表,假设使用(约 800 行 * 平均约 5 条规则),4000 条规则,创建 4000 条 sql 查询并一个接一个地运行它们,直到完成。
  2. 如上所述创建 4000 个“查询”,但一旦完成,只保留唯一/不同的规则,这可能会将计数减少到 1000 'SELECT COUNT(*) FROM... 。
  3. 循环遍历每一行,创建人口表的副本,并从重复表中删除不符合“规则”的行。 这样,行的其余部分的每个条件/查询/规则将在一个越来越小的表上计算。

编辑 - - - - - - - - - - - - - - - - - - -

  • 不幸的是,该表是专有的,但我会尽快使用公共数据创建等效的东西。
  • sql_rules 表是 ~800 行和 8 列(规则)。 大多数时候,单行不包含 8 条规则,因此单行看起来像这样:
行号 规则1 规则_2 规则_3 规则_4 规则_5 规则_6 规则_7 规则_8
头发='蓝色' 眼睛 IN('绿色','棕色') 10000 到 20000 之间的收入 不适用 不适用 不适用 不适用 不适用 不适用

我需要为这个特定行找到的值相当于

行号 规则1 规则_2 规则_3 规则_4 规则_5 规则_6 规则_7 规则_8
从人口中选择数量(*),其中头发 = '蓝色' 从人口中选择计数(*),其中头发 = '蓝色' 和眼睛('绿色','棕色') SELECT COUNT(*) from population WHERE hair = 'blue' AND eyes IN ('green', 'brown') AND income BETWEEN 10000 AND 20000 0 0 0 0 0 0

您可以使用条件 sum ,仍然必须为每组规则构建查询,但where部分可以轻松实现。

select 
  sum(1) filter (where hair_color = 'brown') rule1,
  sum(1) filter (where age < 27) rule2,
  sum(1) filter (where origin in ('US','UK')) rule3
 from population

DB小提琴

暂无
暂无

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

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