Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 用查询过滤的Postgres_Sql_Postgresql_Common Table Expression - Fatal编程技术网

Sql 用查询过滤的Postgres

Sql 用查询过滤的Postgres,sql,postgresql,common-table-expression,Sql,Postgresql,Common Table Expression,我目前有以下疑问: WITH instances AS ( SELECT b.ldtc as date, a.fk_item_id, b.movement, a.quantity, CASE WHEN b.movement = 'Inbound' THEN a.quantity ELSE -a.quantity END as absquantity FROM inventory_resupplylogiteminstance a INNER JOIN i

我目前有以下疑问:

WITH instances AS (
    SELECT b.ldtc as date, a.fk_item_id, b.movement, a.quantity, 
        CASE WHEN b.movement = 'Inbound' THEN a.quantity ELSE -a.quantity END as absquantity
    FROM inventory_resupplylogiteminstance a
    INNER JOIN inventory_resupplylog b ON b.uid = a.fk_resupply_log_id
)

SELECT a.name, 
    SUM(CASE WHEN b.date < ('2018-10-10'::date) THEN b.absquantity END) as starting_balance,

    SUM(CASE WHEN b.date > ('2018-10-10'::date) AND b.date < ('2018-10-12'::date) AND b.movement = 'aa' THEN b.absquantity END) as aa,
    SUM(CASE WHEN b.date > ('2018-10-10'::date) AND b.date < ('2018-10-12'::date) AND b.movement = 'bb' THEN b.absquantity END) as bb,
    SUM(CASE WHEN b.date > ('2018-10-10'::date) AND b.date < ('2018-10-12'::date) AND b.movement = 'cc' THEN b.absquantity END) as cc,
    SUM(CASE WHEN b.date > ('2018-10-10'::date) AND b.date < ('2018-10-12'::date) AND b.movement = 'dd' THEN b.absquantity END) as dd,

    SUM(CASE WHEN b.date < ('2018-10-12'::date) THEN b.absquantity END) AS ending_balance




FROM inventory_item a
LEFT JOIN instances b ON b.fk_item_id = a.uid

GROUP BY a.uid, a.name
ORDER BY a.name

如您所见,第二行到第五行的总和是多余的,因为它们在查询b.date在2018-10-10和2018-10-12之间的行。有没有办法重写我的查询,只需写一次b.date>'2018-10-10'::date和b.date<'2018-10-12'::date,就可以在同一行上选择起始余额和结束余额?

您可以检查CTE中的范围,并创建一个标志,指示该行是否在指定范围内

然后,您可以在最终选择中使用该标志。切换到筛选器表达式也会使其更具可读性:

WITH instances AS (
  SELECT b.ldtc as date, 
         a.fk_item_id, 
         b.movement, 
         a.quantity, 
         CASE 
           WHEN b.movement = 'Inbound' THEN a.quantity 
           ELSE -a.quantity 
         END as absquantity,
         -- the column in_range returns either true or false
         (b.ldtc > ('2018-10-10'::date) AND b.date < ('2018-10-12'::date)) as in_range
  FROM inventory_resupplylogiteminstance a
    INNER JOIN inventory_resupplylog b ON b.uid = a.fk_resupply_log_id
)
SELECT a.name, 
       SUM(b.absquantity) filter (where b.date < '2018-10-10'::date) as starting_balance,
       SUM(b.absquantity) filter (where in_range and b.movement = 'aa') as aa,
       SUM(b.absquantity) filter (where in_range and b.movement = 'bb') as bb,
       SUM(b.absquantity) filter (where in_range and b.movement = 'cc') as cc,
       SUM(b.absquantity) filter (where in_range and b.movement = 'dd') as dd,
       SUM(b.absquantity) filter (where b.date < '2018-10-12'::date) AS ending_balance
FROM inventory_item a
  LEFT JOIN instances b ON b.fk_item_id = a.uid
GROUP BY a.uid, a.name
ORDER BY a.name;
如果您也不想重复开始和结束余额的日期,可以将要测试的范围放入CTE,然后在最终查询中使用Postgres:

WITH instances AS (
  SELECT b.ldtc as date, 
         a.fk_item_id, 
         b.movement, 
         a.quantity, 
         CASE 
           WHEN b.movement = 'Inbound' THEN a.quantity 
           ELSE -a.quantity 
         END as absquantity,
         daterange('2018-10-10'::date, '2018-10-12'::date, '()') as check_range
  FROM inventory_resupplylogiteminstance a
    INNER JOIN inventory_resupplylog b ON b.uid = a.fk_resupply_log_id
)
SELECT a.name, 
    SUM(b.absquantity) filter (where b.date < lower(check_range)) as starting_balance,
    SUM(b.absquantity) filter (where b.date <@ b.check_range and b.movement = 'aa') as aa,
    SUM(b.absquantity) filter (where b.date <@ b.check_range and b.movement = 'bb') as bb,
    SUM(b.absquantity) filter (where b.date <@ b.check_range and b.movement = 'cc') as cc,
    SUM(b.absquantity) filter (where b.date <@ b.check_range and b.movement = 'dd') as dd,
    SUM(b.absquantity) filter (where b.date < upper(b.check_range))) AS ending_balance
FROM inventory_item a
  LEFT JOIN instances b ON b.fk_item_id = a.uid
GROUP BY a.uid, a.name
ORDER BY a.name;
daterange'2018-10-10'::日期,'2018-10-12'::日期,创建一个不包括这两个日期的日期


哇,谢谢一匹没有名字的马,这太干净了!肯定比我想到的要好得多。问题是,我注意到,当b.date<'2018-10-10':date然后b.absquantity结束为起始\ U余额时,您用SUMb.absquantity过滤器替换了SUMCASE,其中b.date