MySQL:从伪视图表更新主表
我有一个主表,比如说MySQL:从伪视图表更新主表,mysql,sql,view,Mysql,Sql,View,我有一个主表,比如说tbl,它有三列。假设我创建了一个表,该表只显示了与col1和col2组合相关的唯一第一条记录。该表的SQL定义如下: CREATE TABLE pseudo_view AS SELECT col1, col2, col3 FROM tbl GROUP BY col1 col2 现在我在这个新表中看到了col1和col2的所有独特组合。我更新此表,以便更改给定记录的col3。我希望通过影响所有重复记录,将其应用回主表tbl 我知道这在标准视图下是不可能的。但是,是否有一种方
tbl
,它有三列。假设我创建了一个表,该表只显示了与col1
和col2
组合相关的唯一第一条记录。该表的SQL定义如下:
CREATE TABLE pseudo_view AS SELECT col1, col2, col3 FROM tbl GROUP BY col1 col2
现在我在这个新表中看到了col1
和col2
的所有独特组合。我更新此表,以便更改给定记录的col3
。我希望通过影响所有重复记录,将其应用回主表tbl
我知道这在标准视图下是不可能的。但是,是否有一种方法可以创建一个依赖表,即当它被更新时,主表将按照select机制的定义进行更新?我需要一个解决方案,这样这个伪视图表可以自由更新和删除其记录,同时也会影响父表。它可以与伪视图和tbl上的一些触发器一起工作 对于tbl上的插入、更新和删除,“视图”需要相应更新。通常这很容易。唯一困难的部分是删除最后一对col1和col2 对于伪_表上的更新和删除,您需要定义主表上应该更改的内容 在我的示例中,我选择了min(3)作为函数,因此当一行被更新时,同一行(用于具有最小col3的那一行)将被更新,并计算psuedotable的新值(可能相同) 当一行被删除时,tbl中的所有行都需要被删除,否则它们也会在pseudo中给出一行(刚才被删除)
对于初学者来说,
SELECT col1,col2,col3 FROM tbl GROUP BY col1 col2
是错误的(col3
是未定义的),除非(col1,col2)
是唯一的键,在这种情况下,无论如何都不需要GROUP BY。@AndreKR:不幸的是,它在MySQL中是有效的(在默认设置下)。但您是对的,它确实为col3
生成了不确定的值(而不是OP认为的“第一个”)@标记哪些行应该受到新“伪”表中更改的影响?(顺便说一句,在我看来这张桌子真是太棒了)。仅具有(已更改)col3
?所有行(具有相同的col1和col2)?@ypercube应影响具有相同的col1
和col2
的所有行。该过程不应区分具有不同col3
值的记录。因此,在tbl
表中确实不需要col3
。只需删除它,在需要时,连接到这个新的(非常真实而不是伪的)表。不幸的情况是,在主表中添加了新记录,在主表中更新了记录,或者从主表中删除了记录。因此,根据您的建议,我还需要SQL之外的编程触发器来处理主表上的插入/更新/删除,而主表上的插入/更新/删除还必须区分伪_视图表上的触发器发送的触发器。您可以在MySQL中使用触发器解决所有这些问题。我很快就会给你一些代码。
CREATE TABLE tbl (col1 INT, col2 INT, col3 INT);
INSERT INTO tbl VALUES (1, 1, 1), (1, 1, 2), (2, 2, 3), (2, 2, 4);
CREATE TABLE pseudo_view
AS
SELECT
col1,
col2,
MIN(col3) AS col3
FROM tbl
GROUP BY col1, col2;
DELIMITER //
-- update the row that originally was the min() and make sure that the new row in pseudo is the new min()
CREATE TRIGGER upd_pseudo
BEFORE UPDATE ON
pseudo_view FOR EACH ROW
BEGIN
UPDATE tbl
SET col3 = NEW.col3
WHERE col1 = OLD.col1
AND col2 = OLD.col2
AND col3 = OLD.col3;
SET NEW.col3 := (SELECT
MIN(col3)
FROM tbl
WHERE col1 = OLD.col1
AND col2 = OLD.col2);
END //
-- delete all rows in tbl that has this col1 and col2
CREATE TRIGGER del_pseudo
AFTER DELETE ON
pseudo_view FOR EACH ROW
BEGIN
DELETE FROM tbl
WHERE col1 = OLD.col1 AND col2 = OLD.col2;
END //
-- update pseudo to make sure it's still true
CREATE TRIGGER upd_tbl
AFTER UPDATE ON
tbl FOR EACH ROW
BEGIN
UPDATE pseudo_view
SET col3 = (SELECT
min(col3)
FROM tbl
WHERE col1 = NEW.col1 AND col2 = NEW.col2)
WHERE col1 = NEW.col1 AND col2 = NEW.col2;
END//
-- update pseudo to make sure it's still true
CREATE TRIGGER ins_tbl
AFTER INSERT ON
tbl FOR EACH ROW
BEGIN
REPLACE pseudo_view
VALUES (NEW.col1, NEW.col2, (SELECT
min(col3)
FROM tbl
WHERE col1 = NEW.col1 AND col2 = NEW.col2));
END//
-- update pseudo to make sure it's still true
CREATE TRIGGER del_tbl
AFTER DELETE ON
tbl FOR EACH ROW
BEGIN
-- todo: add special case when the delete row was the last of that col1/col2-pair
REPLACE pseudo_view
VALUES (NEW.col1, NEW.col2, (SELECT
min(col3)
FROM tbl
WHERE col1 = NEW.col1 AND col2 = NEW.col2));
END//