【问题标题】:Sustract two queries from same table从同一个表中减去两个查询
【发布时间】:2015-02-10 01:50:40
【问题描述】:

假设我有 2 张桌子: 表device是一组测量设备,表data是一组不同类型的设备测量值。

Table data = (no, id,value_type,value, dayhour) no is PK, id refer to table device
Table device = (id, name) id is PK

我目前有一个查询,它将获取特定日期由 id 生成的特定 value_type 的所有值的总和,例如:

SELECT SUM(cast(a.value as int)),b.name FROM data a INNER JOIN device b
ON a.id=b.id 
AND a.id=1
AND a.value_type=2
AND date(a.dayhour)='2015-12-12'
GROUP BY b.name

查询没有问题。现在我希望能够减去不同值类型的总和。我目前正在做的是两个查询,一个用于获取value_type 2 的总和,另一个用于获取value_type 3 的总和,然后在上层过程中进行减法。

但是,我想从单个查询中执行此操作,例如一个查询,它将检索一个总和为 value_type 2 的列,另一列总和为 value_type 3,第三个带有减法在这 2 列中。

【问题讨论】:

  • 请提供正确的表定义:在 psql 或原始 CREATE TABLE 脚本中使用 \d tbl 得到什么。另外,总是:你的 Postgres 版本。

标签: sql postgresql aggregate-functions subtraction


【解决方案1】:
SELECT b.name, a.*, a.sum2 - a.sum3 AS diff
FROM  (
    SELECT id
         , sum(CASE WHEN value_type = 2 THEN value::int END) AS sum2
         , sum(CASE WHEN value_type = 3 THEN value::int END) AS sum3
    FROM   data
    WHERE  id = 1
    AND    value_type IN (2, 3)
    AND    dayhour >= '2015-12-12 0:0'::timestamp
    AND    dayhour <  '2015-12-13 0:0'::timestamp
    GROUP  BY 1
    ) a
JOIN   device b USING (id);
  • 假设dayhour 的数据类型为时间戳(信息缺失)。 迄今为止的演员表将禁用基本索引。这就是我将其转换为sargable 谓词的原因。更多细节:
  • 为什么选择演员value::int
  • 先聚合,然后加入设备。更便宜。

【讨论】:

  • 谢谢!!!!这正是我所需要的。我一直在玩 CASE 语句,但没有找到正确的语法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-07
  • 2013-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-15
相关资源
最近更新 更多