为什么PostgreSQL在这里不责怪'into_res'?

为什么PostgreSQL在这里不责怪'into_res'?,postgresql,Postgresql,我有疑问: SELECT p.*, crate.* into _res FROM LATERAL service_level_tree( 1 ) st -- Get service_level **hierarchy** LEFT JOIN price p ON -- Get Price p.service_level_id = st.id -- for all levels a

我有疑问:

SELECT p.*, crate.*
  into _res
FROM LATERAL service_level_tree( 1 ) st -- Get service_level **hierarchy**
LEFT JOIN price p ON                                -- Get Price
        p.service_level_id = st.id                  --  for all levels at hierarchy
    AND p.service_type_id  = 165       --  for given service
    AND p.period_id        = 10             --  for given period
LEFT JOIN currency_rate crate ON                    -- Get currency rate for conversion
        crate.from_currency_id = p.currency_id      --  from currency of price
    AND crate.to_currency_id   = app_currency()     --  to   requested currency
WHERE p.id IS NOT NULL                              -- Let inheritance to work. Ignore levels without prices
ORDER BY st.depth                                   -- Fetch leaf price first
但当执行它时,我得到了一个错误:

Query execution failed

Reason:
SQL Error [42701]: ERROR: column "id" specified more than once
为什么PostgreSQL将id怪在这里而不是放入存储中?

选择。。。从…进入某张桌子。。。是create table some_table as select的一个有点不推荐的版本

创建新表时,表中的列名必须唯一

错误消息告诉您,price和currency_rate两个表都有一个名为id的列。您的选择列表包含两个表中的所有列,而不重命名它们,因此您的结果至少有两个id列

创建新表时,需要重命名这些列,例如

CREATE TABLE _res
AS
SELECT p.id as price_id, 
       ... other columns from the price table ...
       crate.id as currency_id, 
       ... other columns ...
FROM LATERAL service_level_tree( 1 ) st -- Get service_level **hierarchy**
LEFT JOIN price p ON                                -- Get Price
        p.service_level_id = st.id                  --  for all levels at hierarchy
    AND p.service_type_id  = 165       --  for given service
    AND p.period_id        = 10             --  for given period
LEFT JOIN currency_rate crate ON                    -- Get currency rate for conversion
        crate.from_currency_id = p.currency_id      --  from currency of price
    AND crate.to_currency_id   = app_currency()     --  to   requested currency
WHERE p.id IS NOT NULL                              -- Let inheritance to work. Ignore levels without prices
ORDER BY st.depth   

这是另一个很好的例子,为什么select*通常是糟糕的编码风格。

总是觉得DB应该能够返回关于列的扩展信息。关于列的父级-表。这一栏是那张表上的。关于它的类型。这不会强制用户为返回记录的函数编写列定义。同样,在我的例子中,查询也可以正常工作:不明确的列将有全名:claite.id、p.id和user,如果需要,可以像往常一样设置显式名称。这项功能将减少此类错误的数量,而且更多的事情将会发生。模棱两可的列将有全名——不,它们不会。列名是id,即使您写claite.idies,它在这个级别上也有claite.id。但结果表不能有重复项,因此,如果DB通过将name扩展到claiter.id来解析这些表,那么它将非常方便。然后有人会写res_table.crate.id或res_table.p.id来引用所需的列。但所有这些都只是我的想法