【问题标题】:Is it possible to CREATE TABLE with a column that is a combination of other columns in the same table?是否可以使用由同一表中的其他列组合而成的列来创建表?
【发布时间】:2015-05-10 20:52:25
【问题描述】:

我知道这个问题很长,如果有人没有时间阅读全部内容,我理解,但我真的希望有办法做到这一点。

我正在编写一个程序,它将从数据库目录表中读取数据库模式,并使用从系统目录中提取的信息自动构建一个基本应用程序。

数据库中的很多表可以只是表格的项目列表

CREATE TABLE tablename (id INTEGER PRIMARY KEY, description VARCHAR NOT NULL);

所以当一个表有一个引用idid 的列时,我只需通过从tablename 表中查询它来解析descriptions,然后我在组合框中显示一个可用的列表选项。

但有些表不能直接包含description 列,因为它们的描述将是其他列的组合,让我们以我的第一个应用程序中最重要的表为例

CREATE TABLE bankaccount (
    bankid INTEGER NOT NULL REFERENCES bank,
    officeid INTEGER NOT NULL REFERENCES bankoffice,
    crc INTEGER NOT NULL,
    number BIGINT NOT NULL
);

很多人都知道,这将是银行账户的完整帐号,在我的国家,它的组成如下

[XXXX][XXXX][XX][XXXXXXXXXX]
  ^      ^    ^    ^
bank id  |   crc   account number 
         |
         |_ bank office id 

这就是我的bankaccount 表的结构方式的原因。

现在,我想在description 列中显示完整的银行帐号,这样我就可以在应用程序中显示它而无需对这种情况进行特殊处理,因为还有一些其他表具有类似情况,例如

CREATE TABLE bankaccount (
    bankid INTEGER NOT NULL REFERENCES bank,
    officeid INTEGER NOT NULL REFERENCES bankoffice,
    crc INTEGER NOT NULL,
    number BIGINT NOT NULL, 
    description VARCHAR DEFAULT bankid || '-' || officeid || '-' || crc || '-' || number
);

这当然不起作用,因为引发了以下错误1

ERROR:  cannot use column references in default expression

如果有人可以建议任何不同的方法,请随时提出建议作为答案。


1这是PostgreSQL给出的错误信息。

【问题讨论】:

  • 我对postgres不熟悉,在mssql中你可以添加一个所谓的“计算列”,它是由同一行中其他列的值计算出来的
  • @swe 这个链接很棒,我刚刚学到了一些关于 postgresql 的新东西并且非常有用。

标签: sql database postgresql


【解决方案1】:

你想要的是在你的桌子上创建一个视图。我更熟悉 MySQL 和 SQLite,所以请原谅差异。但基本上,如果你有表'AccountInfo',你可以有一个类似于'存储查询'的视图'AccountInfoView',但可以像表一样使用。你可以用类似的东西来创建它

CREATE VIEW AccountInfoView AS 
SELECT *, CONCATENATE(bankid,officeid,crc,number) AS FullAccountNumber 
FROM AccountInfo

另一种方法是在原始表中创建一个实际的 FullAccountNumber 列,并创建一个触发器,以便在对表执行插入或更新时设置它。但是,这通常效率较低,因为它会复制存储并且在写入而不是检索数据时会降低性能。不过,有时这种方法是有意义的。

【讨论】:

  • 触发思路不错,我等着看有没有人回答,没有的话我就用这个办法。
  • 如果你不能使用视图,触发器肯定是要走的路!
  • 存储完整帐号的唯一充分理由是如果您想对其进行索引。
【解决方案2】:

实际可行,我相信这是一个非常优雅的解决方案,即使用这样的函数

CREATE FUNCTION description(bankaccount) RETURNS VARCHAR AS $$   
    SELECT
        CONCAT(bankid, '-', officeid, '-', crc, '-', number)
    FROM
        bankaccount this
    WHERE
        $1.bankid = this.bankid AND
        $1.officeid = this.officeid AND
        $1.crc = this.crc AND
        $1.number = this.number
$$ LANGUAGE SQL STABLE;

然后会像这样使用

SELECT bankaccount.description FROM bankaccount;

因此,我的目标实现了。

注意:此解决方案仅适用于 PostgreSQL AFAIK。

【讨论】:

    猜你喜欢
    • 2013-12-23
    • 2019-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 2011-03-11
    相关资源
    最近更新 更多