我有2个表:会话和作业。此分配表有一个名为scriptname
的列,其中字符串为值。会话表的列名等于scriptname
+列id
,uid
,timein
和timeout
。当我向分配添加新实例时,我在scriptname
列中获取了新值,我希望将其作为新列添加到默认值为0的会话中。我该怎么做?
我目前正在做的是删除表并根据scriptname
列创建一个新表。问题当然是我丢失了所有数据。
DROP TABLE sessions;
SET SESSION group_concat_max_len = 1000000;
SELECT
CONCAT(
'CREATE TABLE sessions (',
GROUP_CONCAT(DISTINCT
CONCAT(scriptname, ' BOOL DEFAULT 0')
SEPARATOR ','),
');')
FROM
assignments
INTO @sql;
PREPARE stmt FROM @sql;
EXECUTE stmt;
ALTER TABLE sessions
ADD COLUMN `timeout` timestamp not null FIRST,
ADD COLUMN `timein` timestamp not null DEFAULT CURRENT_TIMESTAMP FIRST,
ADD COLUMN `uid` VARCHAR(128) not null FIRST,
ADD COLUMN `id` INT(11) AUTO_INCREMENT PRIMARY KEY not null FIRST;
我希望有人可以帮助我,因为我真的不是sql的专家!提前谢谢。
答案 0 :(得分:8)
相反,请考虑向表中添加行。然后,稍后“转动”以在显示输出时创建列。
正如您所发现的,添加列非常笨拙。添加太多列最终会达到一些限制。添加行基本上是无限的。
在这个论坛中多次讨论了透视,所以我不会在这里重复这些讨论。
答案 1 :(得分:3)
您必须以某种方式知道新添加的列的列表。例如,您可能有一个名为date_added
的列,您在添加新会话时记录了该列。
如果您没有此列,则可以从INFORMATION_SCHEMA.COLUMNS获取列列表。然后您只需要创建一个这样的ALTER TABLE
脚本(这将为4月添加的会话向表中添加新列):
SET SESSION group_concat_max_len = 1000000;
SELECT
CONCAT(
'ALTER TABLE sessions ',
GROUP_CONCAT(DISTINCT
CONCAT('ADD COLUMN ', scriptname, ' BOOL DEFAULT 0')
SEPARATOR ','),
';')
FROM
assignments
WHERE scriptname NOT IN (
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'sessions'
AND table_schema = '<your schema>')
INTO @sql;
PREPARE stmt FROM @sql;
EXECUTE stmt;
-- this should generate this:
-- ALTER TABLE sessions
-- ADD COLUMN blah1 BOOL DEFAULT 0,
-- ADD COLUMN blah2 BOOL DEFAULT 0;
但是,我必须说明您需要重新设计存储数据的方式。存储它的方式不是最佳选择。您需要将会话存储在行中,而不是像您一样存储在列中。如果需要以这种方式显示数据,则可以构建查询以转动数据。
答案 2 :(得分:3)
此处的数据模型较弱。 它不适用于RDBMS - 在那里,您将通过关系强制执行对数据集的限制。
,例如,在您的情况下,通过在scriptname
表中创建sessions
外键。
因此,根据您认为的类型记录,您将在sessions
表中拥有多个记录,每个记录包含1个scriptname值(代表模型中的列名),以及相关值(表格中的字段值)。
然后你可以&#34;旋转&#34;并将这两列组合成客户端的一行。
否则,如果你坚持不惜任何代价保持这种非僵化的非僵化数据结构 - 你最好选择一些面向列的/多模式数据库,比如Apache Cassandra。在那里,你可以随时改变你的columnfamily / table结构,无需停止/删除/重新创建/再次运行。
答案 3 :(得分:2)
正如其他人所说,动态生成不断增长的列列表显然不是你应该做的。 SQL并不是为此而设计的。
在我的位置,根据我对你如何使用它的有限信息,我会有第三个表(有两列:“scriptname”和“value”),它们可以与sessions表连接。这样你就可以在每个会话中拥有任意数量的任务(这听起来像是你的目标)。
答案 4 :(得分:2)
您可以在另一个表格中插入新条目时设置触发器。喜欢 -
CREATE TRIGGER `ADD_COLUMN_BEFORE_INSERT` BEFORE INSERT ON `table_1`
FOR EACH ROW
BEGIN
ALTER TABLE table_2........;
END