简体   繁体   English

将总计行的值拆分为其他多个行,直到总和达到 REDSHIFT 中总计行的值

[英]Split value from a total row to multiple other rows until the sum reaches the value of the total row in REDSHIFT

DB-Fiddle DB-小提琴

CREATE TABLE inbound (
    id SERIAL PRIMARY KEY,
    campaign VARCHAR,
    expected_inbound_date DATE,
    expected_inbound_quantity DECIMAL,
    received_inbound_quantity DECIMAL
);

INSERT INTO inbound
(campaign, expected_inbound_date, expected_inbound_quantity, received_inbound_quantity)
VALUES 
('C001', '2022-05-03', '500', '0'),
('C001', '2022-05-03', '800', '0'),
('C001', '2022-05-03', '400', '0'),
('C001', '2022-05-03', '200', '0'),
('C001', NULL, '0', '700'),

('C002', '2022-08-20', '3000', '0'),
('C002', '2022-08-20', '5000', '0'),
('C002', '2022-08-20', '2800', '0'),
('C002', NULL, '0', '4000');

Expected Result预期结果

campaign |  expected_inbound_date |  expected_inbound_quantity  |  split_received_inbound_quantity
---------|------------------------|-----------------------------|----------------------------------
  C001   |        2022-05-03      |             200             |          200
  C001   |        2022-05-03      |             400             |          400
  C001   |        2022-05-03      |             500             |          100
  C001   |        2022-05-03      |             800             |            0
  C001   |                        |                             |          700
---------|------------------------|-----------------------------|----------------------------------
  C002   |       2022-08-20       |           3.800             |         3.800
  C002   |       2022-08-20       |           5.000             |           200
  C002   |       2022-08-20       |           2.800             |             0
  C002   |                        |                             |         4.000

I want to split the received_inbound_quantity to each row of the expected_inbound_quantity until the total of the received_inbound_quantity is reached.我想将received_inbound_quantity拆分到expected_inbound_quantity的每一行,直到达到received_inbound_quantity的总数。
With reference to the answer in this question I tried to go with this solution:参考这个问题的答案,我尝试使用此解决方案 go:

SELECT
i.campaign AS campaign,
i.expected_inbound_date AS expected_inbound_date,
i.expected_inbound_quantity AS expected_inbound_quantity,
i.received_inbound_quantity AS received_inbound_quantity,

(SELECT 
   GREATEST(
     LEAST(i.expected_inbound_quantity, 
          (SELECT 
           SUM(i3.received_inbound_quantity) 
           FROM inbound i3 
           WHERE i.campaign = i3.campaign)  -
           
            (
                SELECT 
                t1.cumulated_value AS cumulated_value 
                FROM
                
                   (SELECT
                    i2.campaign, 
                    i2.expected_inbound_date, 
                    i2.expected_inbound_quantity, 
                    i2.received_inbound_quantity,
                    SUM(i2.expected_inbound_quantity) OVER (PARTITION BY i2.campaign ORDER BY i2.expected_inbound_date, i2.expected_inbound_quantity, i2.received_inbound_quantity ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) AS cumulated_value
                    FROM inbound i2
                    GROUP BY 1,2,3,4) t1
                    
                WHERE (t1.campaign, t1.expected_inbound_date, t1.expected_inbound_quantity, t1.received_inbound_quantity) = (i.campaign, i.expected_inbound_date, i.expected_inbound_quantity, i.received_inbound_quantity)
            )
            
        ),
        0
   )
) AS split

FROM inbound i
GROUP BY 1,2,3,4
ORDER BY 1,2,3,4

However, in redshift I get error:但是,在 redshift 中我得到错误:

Invalid operation: This type of correlated subquery pattern is not supported yet;

How do I need to modify the query to also make it work in redshift?我需要如何修改查询才能使其在 redshift 中也能正常工作?

Window functions are your friend. Window 函数是你的朋友。 When you have a query that compares rows you should first look to window functions on Redshift.当您有比较行的查询时,您应该首先查看 Redshift 上的 window 函数。 This simpler, cleaner, and faster than any self joining pattern.这比任何自连接模式都更简单、更干净、更快。

select 
  campaign,
  expected_inbound_date,
  expected_inbound_quantity,
  received_inbound_quantity,
  case when (inbound_total - inbound_sum) >= 0 then expected_inbound_quantity
       else case when (expected_inbound_quantity + inbound_total - inbound_sum) >= 0 then expected_inbound_quantity + inbound_total - inbound_sum
                else 0 end
    end as split

from (SELECT
  campaign,
  expected_inbound_date,
  expected_inbound_quantity,
  received_inbound_quantity,
  sum(expected_inbound_quantity) over (partition by campaign order by expected_inbound_date, expected_inbound_quantity) as inbound_sum,
  max(received_inbound_quantity) over (partition by campaign) as inbound_total

  FROM inbound i
) subq
ORDER BY 1,2,3,4; 

Updated fiddle here - https://dbfiddle.uk/?rdbms=postgres_13&fiddle=2381abdf5a90a997a4f05b809c892c40在这里更新小提琴 - https://dbfiddle.uk/?rdbms=postgres_13&fiddle=2381abdf5a90a997a4f05b809c892c40

When you port this to Redshift you may want to convert the CASE statements to DECODE() functions as these are more readable IMHO.当您将其移植到 Redshift 时,您可能希望将 CASE 语句转换为 DECODE() 函数,因为恕我直言,这些函数更具可读性。

PS.附言。 Thank you for setting up the fiddle as this greatly speeds up providing an answer.感谢您设置小提琴,因为这大大加快了提供答案的速度。

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

相关问题 将(Sum)多个 Firebase 个子值加在一起得到总值? - Adding (Sum) multiple Firebase child values together to give a total value? 如何在 flutter 和 firebase 中查找列的总值(总和) - How to find the total value(sum) of a column in flutter and firebase 根据与上一行值的差异跳过 bigquery 中的行 - Skip rows in bigquery based on difference from value in previous row 根据每个行值计算表中的行数 - Count rows in a table based on each row value Redshift 生成的行与另一列中的值一样多 - Redshift generate rows as many as value in another column 根据下一行的值在 sql 中迭代求和? - Sum iteratively in sql based on what value next row has? Elasticsearch 查询未返回求和字段的总值 - Elasticsearch query is not returning a total value of a summed field Amazon Redshift 使用 COPY 命令仅从 JSON 获取 1 行 - Amazon Redshift gets only 1 row from JSON with COPY command 当使用 Javascript UDF 的 BigQuery 中的值低于零时,如何使用多列条件进行运行总计? - How to make running total using multiple columns condition when value below zero in BigQuery using Javascript UDF? 计算一个使用前一行结果的值 - Compute a value that uses result from previous row
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM