【问题标题】:SQL split values on join PostgreSQL连接 PostgreSQL 时的 SQL 拆分值
【发布时间】:2018-10-05 21:18:56
【问题描述】:

我有一张名为production_cost 的表。

product     | per_day_product_cost
------------+-------------------------
powder      | 40

而且,我还有另一个名为 daily_production 的表。

date        | product    | type
------------+------------+----------
2018-09-09  | powder     | talcum
2018-09-09  | powder     | chilli

我需要从连接product 列的两个表中获取结果。 由于每天的总成本为40,我需要将值拆分为两种产品类型,这会导致

date        | product    | type     | cost
------------+------------+----------+--------
2018-09-09  | powder     | talcum   | 20
2018-09-09  | powder     | chilli   | 20

我在使用 count 时尝试了 case,但我没有办法实现最终结果。 我是后端查询的新手,所以如果有任何其他方法可以做到这一点,请告诉我。

【问题讨论】:

  • 这是您唯一的用例吗?或者可以是 3x 辣椒和 2x 滑石粉吗?你会怎么想每件产品的数量是多少?你怎么知道在你的例子中 cost = 40 不是来自 2x 辣椒?
  • @S-Man dateproducttypedaily_production 的复合键。
  • 而且所有单品的价格总是一样的?如果有 4 种成分,那么每种成分的结果成本是 10?那么daily_production中的行数是per_day_product_cost的分隔符吗?

标签: sql postgresql join


【解决方案1】:

您可以尝试使用COUNT 窗口函数从daily_production 表中获取product 的总数。然后编写一个子查询从production_cost 获取每个product 的总成本。

CREATE TABLE  production_cost(
   product VARCHAR(50),
   per_day_product_cost INT
);

INSERT INTO production_cost VALUES ('powder' ,40);

CREATE TABLE daily_production(
   date   TIMESTAMP, product VARCHAR(50), type VARCHAR(50)
);



INSERT INTO daily_production VALUES ('2018-09-09', 'powder','talcum');
INSERT INTO daily_production VALUES ('2018-09-09', 'powder','chilli');

查询 1

SELECT *,(
    select SUM(per_day_product_cost)  
    from production_cost pc
    WHERE pc.product = dp.product
    GROUP BY pc.product) /COUNT(*) OVER(PARTITION BY product ORDER BY product) as cost
FROM daily_production dp 

Results

|                 date | product |   type | cost |
|----------------------|---------|--------|------|
| 2018-09-09T00:00:00Z |  powder | talcum |   20 |
| 2018-09-09T00:00:00Z |  powder | chilli |   20 |

【讨论】:

  • 我没有相同的表。但我确实具有与子查询相同的结构,而不是表。对您提供的答案进行修改。会让你知道的。
  • @D-Shih 为什么使用SUM() 子选择?该表谈到“每天的成本”。我为什么要总结这些价值观?我误解了用例吗?无论如何都是不错的解决方案(+1)。
  • 您可能应该将日期添加到您的 PARTITION 中,因为开启者意味着日期是密钥的一部分。如果有一个日期,粉末是由一些神奇的神秘材料制成的,那么将只有一种原料,成本为 40。或者当有两天用滑石粉和辣椒生产粉末时,你的分频器会增加到 4。我认为这不是预期的。
  • 看这个小提琴:dbfiddle.uk/…
【解决方案2】:

在下面尝试使用子查询来计算产品类型计数,然后使用计数来划分产品的总成本

select d.date,d.product,d.type,(p.per_day_product_cost/c) as cost
from product p
inner join
(select product,count(type) as c from daily_production
group by product)a on p.product=a.product
inner join daily_production d on p.product=d.product

【讨论】:

    【解决方案3】:

    使用连接和子查询

    select t1.*,t2.cost from 
    (
     select p.* from production_cost c 
     join daily_production p
     on c.product=p.product
    ) as t1 join 
    ( 
    select p.product, c.per_day_product_cost/count(p.product) as cost
      from production_cost c 
       join 
     daily_production p
    on c.product=p.product
    group by p.product,c.per_day_product_cost
    ) as t2 
    on t1.product=t2.product
    
    
    date                    product type   cost
    09/09/2018 00:00:00     powder  talcum  20
    09/09/2018 00:00:00     powder  chilli  20
    

    Result demo

    【讨论】:

      【解决方案4】:

      免责声明:这仅适用于所有单一产品的成本始终完全相同的情况。如果一种成分可能是成本为 100 的黄金,而另一种是成本为 10 的木材,则不再适用。我假设每种产品的成分数量是整个产品成本的除法器。


      使用窗口函数COUNT(https://www.postgresql.org/docs/current/static/tutorial-window.html):

      demo: db<>fiddle

      SELECT 
          dp.*, 
          pc.per_day_product_cost / 
               count(*) OVER (PARTITION by pc.product, dp.prod_date) as cost
      FROM
          daily_production dp
          JOIN production_cost pc
          ON dp.product = pc.product
      

      COUNT 窗口函数将行分组。在您的情况下,为每个日期和产品创建一个组。然后它计算这些组中的所有行。此结果将作为您的per_day_production_cost 的分隔符,并设置为每一行的新列。


      请注意,“日期”是 Postgres 中的保留字。最好重命名您的列。我将它重命名为“prod_date”。

      【讨论】:

        【解决方案5】:
        select 
            d.date, 
            d.product, 
            d.type, 
            p.per_day_product_cost/(select count(1) 
                                    from daily_production d1 
                                    where d1.product=d.product and d1.date=d.date) cost 
        from daily_production d,production_cost p 
        where d.product=p.product;
        

        【讨论】:

        • 请将日期更改为 billing_date 或其他任何内容,因为日期是数据类型之一
        猜你喜欢
        • 2011-08-01
        • 1970-01-01
        • 2023-03-11
        • 2018-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多