如何进行选择并能够退回到默认值?

时间:2019-04-11 12:51:01

标签: mysql sql

希望我能清楚地问这个问题。...如果不能,请告诉我,我会及时进行修改。

这个问题围绕我的帐户设置表(account_data)...基本上,如果一个帐户在表中有一个条目,则定义了该设置...如果没有,那么我需要加载默认值(account_id一片空白)。表结构:

arm-none-eabi

快速说明:account_id可以(但不确定)是帐户表id列的外键。

示例数据集:

     CREATE TABLE `account_data` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `account_id` int(11) DEFAULT NULL,
      `name` varchar(255) NOT NULL,
      `value` varchar(255) NOT NULL,
      `updated` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
      `created` datetime DEFAULT CURRENT_TIMESTAMP,
     PRIMARY KEY (`id`),
     UNIQUE KEY `id` (`id`),
     UNIQUE KEY `account_id_name` (`account_id`,`name`) USING BTREE,
     KEY `account_id` (`account_id`)
     ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

因此,目前我正在执行以下操作,以获取帐户的单个设置值...

account_id | name | value
null | email_allowed | 0
1 | email_allowed | 1
null | persist_login | 0
null | homepage_version | small

这似乎很好...如果出于任何原因这不是一个好主意,我都想听听为什么。但是,当我需要获取单个帐户的所有account_data值时,我正在执行两个查询。...

     SELECT * FROM account_data WHERE `name` = :name AND (account_id = :account_id OR account_id IS NULL) ORDER BY account_id DESC LIMIT 1

    SELECT * FROM account_data WHERE account_id = :account_id

然后将它们合并到我的代码中。...是否有一种方法可以仅通过一个查询来做到这一点?

2 个答案:

答案 0 :(得分:1)

一种解决方案可能是通过将表自身连接起来来创建一个包含默认值的新列:

CREATE OR REPLACE FUNCTION make_into_serial(table_name TEXT, column_name TEXT) RETURNS INTEGER AS $$
DECLARE
    start_with INTEGER;
    sequence_name TEXT;
BEGIN
    sequence_name := table_name || '_' || column_name || '_seq';
    EXECUTE 'SELECT coalesce(max(' || column_name || '), 0) + 1 FROM ' || table_name
            INTO start_with;
    EXECUTE 'CREATE SEQUENCE ' || sequence_name ||
            ' START WITH ' || start_with ||
            ' OWNED BY ' || table_name || '.' || column_name;
    EXECUTE 'ALTER TABLE ' || table_name || ' ALTER COLUMN ' || column_name ||
            ' SET DEFAULT nextVal(''' || sequence_name || ''')';
    RETURN start_with;
END;
$$ LANGUAGE plpgsql VOLATILE;

答案 1 :(得分:1)

这里的窍门是您没有所有设置。如果不是全部都是默认值,那么这会有些麻烦。

优先级查询如何?

select a.*
from account_data a
where account_id = :account_id
union all
select a.*
from account_data a
where account_id is null and
      not exists (select 1
                  from account_data ad2
                  where ad2.name = ad.name and
                        ad2.account_id = :account_id
                 );

这应该获得所有默认值(不匹配)以及该帐户的所有设置)。