【问题标题】:Create a view that contains in every row data that comes from six different records[PostgreSQL]创建一个视图,其中包含来自六个不同记录的每一行数据[PostgreSQL]
【发布时间】:2016-02-13 22:54:21
【问题描述】:

我有一张包含加油站价格的表格。每个加油站都有六种不同燃料类型(柴油、普通、超级)和服务类型(汽车服务、全方位服务)的价格记录。例如,我在“gas_station_prices”表中有“id_gas_station”=155 的加油站价格记录

id_price|price_gas_station|id_gas_station|id_fuel_type|id_service_type
3041    |2.29             |155           |2           |1
2631    |2.52             |155           |1           |1
3861    |2.43             |155           |1           |2    
4681    |1.84             |155           |3           |2    
3451    |1.93             |155           |3           |1    
4271    |2.2              |155           |2           |2    

我有两个包含燃料类型和服务类型的目录

fuel_type 目录:

id_fuel_type |name_fuel_type
1            |SUPER
2            |REGULAR
3            |DIESEL

service_type 目录:

id_service_type |name_service_type
1               |FULL SERVICE
2               |AUTO SERVICE

我需要为每个 gas_station 创建一个 SQL VIEW,其中包含“price_gas_station”列的六个记录价格的并集,如下所示:

id_gas_station|fs_sup_p |fs_reg_p |fs_die_p |as_sup_p |as_reg_p|as_die_p|
155           |2.52     |2.29     |1.93     |2.43     |2.2     |1.84

【问题讨论】:

    标签: sql postgresql view sql-function


    【解决方案1】:

    您可以使用条件聚合

    SELECT id_gas_station,
           MAX(CASE WHEN id_fuel_type = 1 AND 
                         id_service_type = 1 
                    THEN price_gas_station 
               END) AS fs_sup_p, 
           MAX(CASE WHEN id_fuel_type = 2 AND 
                         id_service_type = 1
                    THEN price_gas_station 
               END) AS fs_reg_p, 
           MAX(CASE WHEN id_fuel_type = 3 AND 
                         id_service_type = 1
                    THEN price_gas_station 
               END) AS fs_die_p, 
           ... etc
    FROM mytable
    GROUP BY id_gas_station
    

    【讨论】:

      【解决方案2】:

      这是使用 CROSSTAB 的另一种方式 (http://www.postgresql.org/docs/current/static/tablefunc.html)

      SELECT *
      FROM crosstab(
      '
      SELECT
          gsp.id_gas_station,
          LOWER(LEFT(st.name_service_type,4) || ft.name_fuel_type) AS price_type,
          gsp.price_gas_station
      FROM
          gas_station_prices gsp
      JOIN
          fuel_type ft
          ON  (ft.id_fuel_type = gsp.id_fuel_type)
      JOIN
          service_type st
          ON  (st.id_service_type = gsp.id_service_type)
      ORDER BY
          1,2
      '
      ) AS ct (
      id_gas_station INT,
      auto_diesel FLOAT,
      auto_regular FLOAT,
      auto_super FLOAT,
      full_diesel FLOAT,
      full_regular FLOAT,
      full_super FLOAT
      );
      

      Giorgos 解决方案应该也一样好 - 或许也更具可读性?在大多数情况下,这是一个偏好问题。我只是想告诉你一个替代方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-13
        • 2017-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多