【问题标题】:Creating view from item table and price table从项目表和价格表创建视图
【发布时间】:2019-12-23 23:28:49
【问题描述】:

假设我有两张桌子。一个是订单表,另一个是价格表,给出商品 w.r.t 的价格。订购的商品数量。 test_price 表的含义是“最多 count 个项目(含)每个项目的成本是 price”。因此,0-50 件商品每件售价 1.22。 51-100 每件成本 1.20。

table test_price

id | count | price 
----+-------+-------
  1 |    50 |  1.22
  2 |   100 |  1.20
  3 |   150 |  1.19
  4 |   200 |  1.18
  5 |   300 |  1.10

table test_orders
 id | count 
----+-------
  1 |    12
  2 |    50
  3 |    65
  4 |   155
  5 |   400

因此这意味着 12 件商品的订单 1 的价格应为每件 1.22。 订单 5 的价格应为每件 1.10。

我可以得到一个订单的价格

SELECT price FROM test_prices WHERE 
count >= (SELECT count FROM test_orders WHERE id = 1) 
ORDER BY count ASC LIMIT 1;

我想创建一个视图,以单价和总价作为列显示订单

【问题讨论】:

  • 您的价格表没有意义。其中没有12。而且好像没有1数量的价格。
  • 嗨!将列命名为“count”时要小心,因为 count() 也是一个组函数。这可能非常模棱两可。

标签: sql postgresql


【解决方案1】:

我认为您的test_prices 表不太正确。我认为应该是:

id | count | price 
----+-------+-------
  1 |    1  |  1.22
  2 |   100 |  1.20
  3 |   150 |  1.19
  4 |   200 |  1.18
  5 |   300 |  1.10

这表示 1-99 数量的价格为 1.22 美元。 100-149,价格$1.20,以此类推。

通过这种结构,您可以使用横向连接:

select o.*, p.price
from test_orders o left join lateral
     (select p.*
      from test_prices p
      where p.count <= o.count
      order by p.count desc
      fetch first 1 row only
     ) p
     on 1=1

【讨论】:

    【解决方案2】:

    应用您的条件加入count 列上的表格:

    with cte as (select max(count) maxcount from test_price)
    select
      o.*, o.count * p.price total_price
    from test_orders o inner join test_price p
    on p.count = coalesce(
      (select min(count) from test_price where o.count <= count),
      (select maxcount from cte)
    )
    order by o.id;
    

    请参阅demo
    结果:

    | id  | count | total_price |
    | --- | ----- | ----------- |
    | 1   | 12    | 14.64       |
    | 2   | 50    | 61          |
    | 3   | 65    | 78          |
    | 4   | 155   | 182.9       |
    | 5   | 400   | 440         |
    

    【讨论】:

      【解决方案3】:

      您的数据的问题在于 price_table 数据并非全部“最多”,因为第 5 行也意味着“最多”。 如果您能够像(6, 10000, 1.10) 一样向price_table 添加另一行,那么解决方案很简单:

      CREATE VIEW price_view AS
      SELECT orders.id, orders.count, p.price, orders.count * p.price as total
      FROM (
        SELECT o.id, o.count, min(p.count) as pricebracket
        FROM test_price p 
        LEFT JOIN test_orders o ON p.count >= o.count
        GROUP BY o.id, o.count) orders
      LEFT JOIN test_price p ON orders.pricebracket = p.count
      ORDER BY orders.id
      

      如果您无法消除数据中的这种不一致,那么您必须首先选择最大值。所以查询修改如下:

      CREATE VIEW price_view AS
      WITH temptable as (SELECT max(p.count) as maxcount FROM test_price p)
      SELECT orders.id, orders.count, p.price, orders.count * p.price as total
      FROM (
         SELECT o.id, o.count, min(p.count) as pricebracket
         FROM test_price p 
         CROSS JOIN temptable
         LEFT JOIN test_orders o ON p.count >= 
             (case when o.count > temptable.maxcount then temptable.maxcount else o.count end)
         GROUP BY o.id, o.count) orders
      LEFT JOIN test_price p ON orders.pricebracket = p.count
      ORDER BY orders.id
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-06
        • 2011-10-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多