SQL Cartesian产品将表连接到自身并插入到现有表中

时间:2014-05-30 08:40:23

标签: sql join

我正在使用SQL在phpMyadmin中工作。 我想从TableA中获取主键(EntryID)并在TableB中创建一个笛卡尔积(如果我正确使用该术语)(已创建空表),对于TableA中与FieldB共享相同值的所有条目,除了TableA .EntryID等于TableA.EntryID 因此,例如,如果TableA中的值为:

TableA.EntryID   TableA.FieldB
1                        23
2                        23
3                        23
4                        25
5                        25
6                        25

TableB中的结果是:

Primary key       EntryID1         EntryID2      FieldD (Default or manually entered)
1                       1                    2                    Default value
2                       1                    3                    Default value
3                       2                    1                    Default value
4                       2                    3                    Default value
5                       3                    1                    Default value
6                       3                    2                    Default value
7                       4                    5                    Default value
8                       4                    6                    Default value
9                       5                    4                    Default value
10                      5                    6                    Default value
11                      6                    4                    Default value
12                      6                    5                    Default value

我习惯在Access中工作,这是我在SQL中尝试过的第一个查询 我开始尝试解决这个问题并且做到了这一点。我知道它还不对,因为我仍然习惯于习惯语法并将其与我在网上找到的各种文章拼凑在一起。特别是,我不确定INSERT INTO文本的去向(创建Access中的附加查询)。

SELECT EntryID 
FROM TableA.EntryID
       TableA.EntryID 
WHERE TableA.FieldB=TableA.FieldB
         TableA.EntryID<>TableA.EntryID
INSERT INTO TableB.EntryID1 
            TableB.EntryID2

我得到了正确的查询后,我需要进行TRIGGER查询(我认为),所以如果一个条目在TableA.FieldB中更改了它的值(将该组的成员身份更改为另一个分组),则为笛卡尔积将在该条目上重新运行,除非TableB.FieldD = valueA或valueB(手动输入的值)。

我一直在使用Designer标签。 TableA和TableB之间是否存在关系链接。如果是这样,它会是TableA中的EntryID主键的两个链接,一个是TableB中的每个EntryID吗?我认为这不起作用,因为它们编号为EntryID1和EntryID2,并且名称需要相同才能建立关系?

如果你能提出任何建议,我将非常感激。

研究: http://www.fluffycat.com/SQL/Cartesian-Joins/ 笛卡尔加入例二 问:你说你可以通过加入一张表来自己进行笛卡尔连接。显示!
    选择 *     来自Film_Table T1,         Film_Table T2;

2 个答案:

答案 0 :(得分:0)

这应该给你'笛卡儿'(它实际上不是笛卡儿,正如@ThorstenKettner在下面提到的 - 它是一个自我联接),你要追求它,并将其插入TableB

INSERT INTO TableB (EntryId1, EntryId2, fieldD)
SELECT a.EntryID, b.EntryID, 'Default Value'
FROM TableA a, TableA b
WHERE a.FieldB=b.FieldB
AND a.EntryID<>b.EntryID

触发器的两个表之间不需要任何关系,但我建议你设置一个外键关系,这样你就永远不会在TableB.EntryID1TableB.EntryID2中输入一个条目在TableA.EntryID ..

中没有相应的条目

对于触发器,你可以为插件做这样的事情(在这种情况下你不需要检查TableB,因为你知道你的新TableA.EntryId还不存在:

CREATE TRIGGER ins_tableA AFTER INSERT ON TableA
FOR EACH ROW
BEGIN
    INSERT INTO TableB (EntryId1, EntryId2, fieldD)
    SELECT a.EntryID, b.EntryID, 'Default Value'
    FROM TableA a, TableA b
    WHERE a.FieldB=b.FieldB
    AND a.EntryID=NEW.EntryID
    AND a.EntryID<>b.EntryID;

END;

对于更新,您可以先从TableB删除所有相应的行,然后重新运行插入。像这样:

CREATE TRIGGER upd_tableA AFTER UPDATE ON TableA
FOR EACH ROW
BEGIN
    DELETE FROM TableB b
    WHERE b.EntryId1 = NEW.EntryId
    OR b.EntryId2 = NEW.EntryId;

    INSERT INTO TableB (EntryId1, EntryId2, fieldD)
    SELECT a.EntryID, b.EntryID, 'Default Value'
    FROM TableA a, TableA b
    WHERE a.FieldB=b.FieldB
    AND a.EntryID=NEW.EntryID
    AND a.EntryID<>b.EntryID;

END;

我担心这些都没有经过测试,但希望它会让你走上正轨......

答案 1 :(得分:0)

不,你不想要一个笛卡尔产品,你可以在没有任何条件的情况下加入桌子。您正在寻找的是一个简单的自我加入:

insert into TableB(EntryID1, EntryID2)
select x.EntryID, y.EntryID
from TableA x
join TableA y on x.FieldB = y.FieldB and x.EntryID <> y.EntryID;

编辑:由于您希望此表始终保持最新状态,请考虑使用视图而不是表(仅适用于手动维护的FieldD)。