SQL笛卡尔乘积将表连接到自身并插入到现有表中

SQL笛卡尔乘积将表连接到自身并插入到现有表中,sql,join,Sql,Join,我正在使用SQL在phpMyadmin中工作。 我想从TableA中获取主键(EntryID),并在TableB(已创建的空表)中为所有共享TableA中FieldB相同值的条目创建笛卡尔积(如果我正确使用了该术语),TableA.EntryID等于TableA.EntryID的情况除外 例如,如果表A中的值为: TableA.EntryID TableA.FieldB 1 23 2 23 3

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

TableA.EntryID   TableA.FieldB
1                        23
2                        23
3                        23
4                        25
5                        25
6                        25
表B中的结果是:

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中尝试的第一个查询。
我开始尝试解决这个问题,并且走了这么远。我知道它还不正确,因为我仍在努力适应语法,并从我在网上找到的各种文章中拼凑出来。特别是,我不确定插入文本的位置(在Access中创建追加查询)

选择EntryID
从表A.EntryID
表a.EntryID
其中TableA.FieldB=TableA.FieldB
表A.EntryID表A.EntryID
在表B中插入条目1
表B.EntryD2
在我得到正确的查询之后,我需要执行一个触发器查询(我想),因此如果一个条目更改了TableA.FieldB中的值(将该分组的成员身份更改为另一个分组),笛卡尔乘积将在该条目上重新运行,除非TableB.FieldD=valueA或valueB(手动输入的值)

我一直在使用Designer选项卡。表a和表B之间是否必须存在关系链接。如果是这样,是否会有两个链接从表A中的EntryID主键连接到表B中的每个EntryID?我假设这不起作用,因为它们分别编号为EntryD1和EntryD2,并且名称必须相同才能建立关系

如果你能提供任何建议,我将不胜感激

研究: 笛卡尔连接示例二 问:你说过你可以通过将一个表连接到它本身来进行笛卡尔连接。给我看看
挑选* 从表T1中,
胶片表T2

这应该给你你想要的“笛卡尔”(它实际上不是笛卡尔,正如@ThorstenKettner在下面提到的-它是一个自联接),然后将它插入到
表B

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
中删除所有对应的行,然后重新运行insert。大概是这样的:

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;
更新表A后创建触发器upd_表A
每行
开始
从表b中删除
其中b.entryd1=NEW.EntryId
或者b.entryd2=NEW.EntryId;
插入表B(条目1、条目2、字段D)
选择a.EntryID,b.EntryID,“默认值”
从表a到表b
其中a.FieldB=b.FieldB
a.EntryID=NEW.EntryID
和a.entrydb.EntryID;
终止

恐怕这一切都没有经过测试,但希望它能让您走上正轨。

不,您不需要笛卡尔积,在笛卡尔积中,您可以无条件地连接表。您需要的是一个简单的自连接:

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;
插入到表B中(entryD1,entryD2)
选择x.EntryID,y.EntryID
从表A到表x
在x.FieldB=y.FieldB和x.EntryID y.EntryID上连接表a和y;

<>编辑:当你希望这个表一直是最新的时候,考虑一个视图而不是一个表(只有这样,你就不能有一个手动维护的字段)。数据编辑包括对现有数据重新分组以及添加新条目。我们需要将其自动化,因为多个用户将进行修改,因此无法手动删除条目。谢谢霍斯特·凯特纳。非常感谢。如果它是一个没有笛卡尔积的简单连接,它是否仍然生成组内所有可能的组合(EntryID=EntryID除外)?是的。只需尝试一下(删除插入行以仅执行select语句)。然而,斯蒂夫给了你同样的陈述。我只是想澄清一下,这不是笛卡尔积。您需要存储一个fieldD,还是可以从数据库中的其他数据收集信息?如果这些信息可以随时收集,那么一个视图就完美了。它将始终是最新的,因为它不保存任何数据,而只指定select语句。如果必须存储fieldD:它对于FieldB不是唯一的,但必须按照FieldID1-FieldID2组合进行设置?如果它对于FieldB是唯一的,那么您可以拥有一个tableB并将字段存储在那里。如果必须在FieldID1-FieldID2上维护,则按照您自己的建议和StevieG的解释,使用触发器。
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;
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;