【问题标题】:Rewrite Select SQL query for PostgreSQL为 PostgreSQL 重写 Select SQL 查询
【发布时间】:2016-05-14 09:44:30
【问题描述】:

我基于这个主题在 PostgreSQL 中创建了这些表:

Database design for user settings

-- TABLE SETTING

CREATE TABLE SETTING(
 ID INTEGER NOT NULL,
 DESCRIPTION TEXT,
 CONSTRAINED TEXT,
 DATA_TYPE TEXT,
 MIN_VALUE TEXT,
 MAX_VALUE TEXT
)
;

-- ADD KEYS FOR TABLE SETTING

ALTER TABLE SETTING ADD CONSTRAINT KEY34 PRIMARY KEY (ID)
;

-- TABLE ALLOWED_SETTING_VALUE

CREATE TABLE ALLOWED_SETTING_VALUE(
 ID INTEGER NOT NULL,
 SETTING_ID INTEGER,
 ITEM_VALUE TEXT,
 CAPTION TEXT
)
;

-- CREATE INDEXES FOR TABLE ALLOWED_SETTING_VALUE

CREATE INDEX IX_RELATIONSHIP16 ON ALLOWED_SETTING_VALUE (SETTING_ID)
;

-- ADD KEYS FOR TABLE ALLOWED_SETTING_VALUE

ALTER TABLE ALLOWED_SETTING_VALUE ADD CONSTRAINT KEY35 PRIMARY KEY (ID)
;

-- TABLE USER_SETTING

CREATE TABLE USER_SETTING(
 ID INTEGER NOT NULL,
 USER_ID INTEGER,
 SETTING_ID INTEGER,
 ALLOWED_SETTING_VALUE_ID INTEGER,
 UNCONSTRAINED_VALUE TEXT
)
;

-- CREATE INDEXES FOR TABLE USER_SETTING

CREATE INDEX IX_RELATIONSHIP15 ON USER_SETTING (SETTING_ID)
;

CREATE INDEX IX_RELATIONSHIP17 ON USER_SETTING (ALLOWED_SETTING_VALUE_ID)
;

-- ADD KEYS FOR TABLE USER_SETTING

ALTER TABLE USER_SETTING ADD CONSTRAINT KEY36 PRIMARY KEY (ID)
;

但是当我运行 Select SQL 查询时,我得到了错误,因为它是针对 MySQL 的:

-- Show settings for a given user
select
  US.user_id 
, S1.description 
, S1.data_type 
, case when S1.constrained = 'true'
  then AV.item_value
  else US.unconstrained_value
  end value
, AV.caption
from USER_SETTING US
  inner join SETTING S1
    on US.setting_id = S1.id 
  left outer join ALLOWED_SETTING_VALUE AV
    on US.allowed_setting_value_id = AV.id
where US.user_id = 234

结果

ERROR:  syntax error at or near "value"
LINE 8:   end value

我可以为 PostgreSQL 重写这个 SQL 查询吗?

【问题讨论】:

  • 这是有效的标准 SQL,尝试添加 AS:AS value(我刚刚在 Fiddle 上尝试过,并且成功了)。似乎是一个奇怪的解析错误。
  • 是的,这解决了问题。谢谢!

标签: sql postgresql postgresql-9.1 postgresql-9.3


【解决方案1】:

value是保留关键字,需要在SQL中引用:

case when S1.constrained = 'true'
    then AV.item_value
    else US.unconstrained_value
end "value"

添加as 关键字有效,因为这消除了value 可能的歧义。但最好还是引用它 - 即使使用 as 关键字(或找到其他名称)。

This behaviour is documented 并且手册明确提到了关键字value

AS 关键字是可选的,但前提是新列名不匹配任何 PostgreSQL 关键字(请参阅附录 C)。为避免与关键字意外匹配,您可以将列名用双引号引起来。例如,VALUE 是一个关键字,所以这不起作用:

SELECT a value, b + c AS sum FROM ...

但确实如此:

SELECT a "value", b + c AS sum FROM ...

为防止将来可能添加关键字,建议您始终编写 AS 或双引号输出列名。


不相关,但是:

您不应在 text 列中存储布尔值(truefalse)。 Postgres 对此有一个原生的boolean 数据类型。

【讨论】:

    猜你喜欢
    • 2016-07-19
    • 1970-01-01
    • 1970-01-01
    • 2016-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-08
    • 1970-01-01
    相关资源
    最近更新 更多