如何在PostgreSQL中通过查询编写组

时间:2019-03-25 12:52:41

标签: postgresql

按查询写入群组时,PostgreSQL出现错误, 确保有人会告诉我将我选择的所有列都放在分组依据中,但这不会给我正确的结果。

正在编写一个查询,该查询将选择数据库中的所有车辆并按车辆分组结果,从而给出给定期间的总距离和成本。

这是查询的方式。

class TheComponent extends Component{
    constructor(props) {
        super(props);
        this.state = {
            a: '',
            b: ''
        };
     }

     setValues = (data) => {
        this.setState({
            a: data.a,
            b: data.b
        });
      }

     outputValues = () => {
         console.log(this.state);
     }

      render(){
        return (
            <ChildrenComponent set={this.setValues} output={this.outputValues}/>
            <p>{this.state.a}</p>
        );
      }
    }

如果我将所有在bt组中的select列都放在bt组中,结果将不正确。

如何在不将所有列归为一组并创建子查询的情况下进行此操作?

燃油表如下:

class ChildrenComponent extends Component{
      render() {
        const data = { a: 'foo', b: 'bar' };
        return (
            <button onClick={() => this.props.set(data)}>change parent state</button>
            <button onClick={this.props.outputValues}>console.log parent state</button>
        );
      }
    }

车辆表

SELECT i.vehicle AS vehicle,
i.costcenter AS costCenter,
i.department AS department,
SUM(i.quantity) AS liters,
SUM(i.totalcost) AS Totalcost,
v.model AS model,
v.vtype AS vtype
FROM fuelissuances AS i 
LEFT JOIN vehicles AS v ON i.vehicle = v.id
WHERE i.dates::text LIKE '%2019-03%' AND i.deleted_at IS NULL
GROUP BY i.vehicle;

这是我希望从查询中获得的结果

vehicle     dates           department      quantity        totalcost
1           2019-01-01      102             12              1200
1           2019-01-05      102             15              1500
1           2019-01-13      102             18              1800
1           2019-01-22      102             10              1000
2           2019-01-01      102             12              1260 
2           2019-01-05      102             19              1995
2           2019-01-13      102             28              2940

2 个答案:

答案 0 :(得分:0)

您需要使用嵌套查询来在查询中获取所需的SUM

SELECT i.vehicle AS vehicle,
i.costcenter AS costCenter,
i.department AS department,
(SELECT SUM(i.quantity) FROM TABLES WHERE CONDITIONS GROUP BY vehicle) AS liters,
(SELECT SUM(i.totalcost) FROM TABLES WHERE CONDITIONS GROUP BY vehicle) AS Totalcost,
v.model AS model,
v.vtype AS vtype
FROM fuelissuances AS i 
LEFT JOIN vehicles AS v ON i.vehicle = v.id
WHERE i.dates::text LIKE '%2019-03%' AND i.deleted_at IS NULL;

答案 1 :(得分:0)

您的查询没有任何意义。在fuelissuances表中,每辆车显然可以有多个部门和成本中心-应该返回哪些?

一种解决方法是将它们全部退还,例如作为数组:

SELECT i.vehicle,
       array_agg(i.costcenter) as costcenters,
       array_agg(i.department) as departments,
       SUM(i.quantity) AS liters,
       SUM(i.totalcost) AS Totalcost,
       v.model,
       v.vtype
FROM fuelissuances AS i 
   LEFT JOIN vehicles AS v ON i.vehicle = v.id
WHERE i.dates >= date '2019-03-01' 
  and i.date < date '2019-04-01' 
  AND i.deleted_at IS NULL
group by i.vehicle, v.model, v.vtype;

您也可以返回用逗号分隔的这些值列表,而不是数组,例如string_agg(i.costcenter, ',') as costcenters

添加列v.modelv.vtype不会(不应)进行任何更改,因为group by i.vehicle只会返回单个车辆,因此模型和vtype不会在组中进行更改。

请注意,我删除了无用的别名,并将日期上的条件替换为可以利用dates列上的索引的适当范围条件。


修改

基于新的样本数据,您需要一个总计,而不是“常规”聚合。使用window functions

可以轻松完成此操作
SELECT i.vehicle,
       i.costcenter,
       i.department,
       SUM(i.quantity) over (w) AS liters,
       SUM(i.totalcost) over (w) AS Totalcost,
       v.model,
       v.vtype
FROM fuelissuances AS i 
   LEFT JOIN vehicles AS v ON i.vehicle = v.id
WHERE i.dates >= date '2019-01-01' 
  and i.dates < date '2019-02-01' 
  AND i.deleted_at IS NULL
window w as (partition by i.vehicle order by i.dates)  
order by i.vehicle, i.dates;

我不会使用SQL创建这些“总计”行,而是在您的前端显示数据。

在线示例:https://rextester.com/CRJZ27446