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//