【问题标题】:Join table on itself without two queries在没有两个查询的情况下自行连接表
【发布时间】:2012-03-25 14:13:27
【问题描述】:

我看到有人建议通过这样做来交叉加入一个表:

SELECT *
FROM tbl AS A, tbl AS B
WHERE A.col1 = 1 AND B.col1 = 1

但是在这里,引擎需要遍历 tbl 中的所有行两次,以将两个查询与 A 和 B 的结果相匹配,尽管查询(因此结果)是相同的。

假设 A 和 B 上的 WHERE 对于两者来说总是相同的,这是一种浪费。有什么方法可以查询一次,然后交叉连接该查询的结果本身?我想避免使用临时表,这需要写入磁盘而不是在 RAM 中执行整个操作。

我正在使用 MySQL,尽管任何 SQL 答案都会有很大帮助。

示例:

假设 tbl 如下所示:

COL1    COL2
1       A
1       B
1       C
2       D
2       E

当我运行 col1 = 1 的 where 子句时,它会返回上表的前三行。我想要的是下表,但只执行一次 where 语句,因为两个表 A 和 B 是相同的:

A.COL1    A.COL2    B.COL1    B.COL2
1         A         1         A
1         A         1         B
1         A         1         C
1         B         1         A
1         B         1         B
1         B         1         C
1         C         1         A
1         C         1         B
1         C         1         C

【问题讨论】:

标签: mysql sql join cross-join


【解决方案1】:

你基本上是在要求一个有意的笛卡尔连接

select
      a.col1,
      a.col2,
      b.col1,
      b.col2
   from
      tbl a
         join tbl b
            on a.col1 = b.col1
   where
      a.col1 = 1
   order by
      a.col2,
      b.col2

要准确地达到您的输出顺序,您需要按“a”第 2 列然后“b”第 2 列排序

【讨论】:

    【解决方案2】:

    我真的建议避免使用 JOIN 语法……它可能很难阅读。

    您对您正在尝试做的事情的解释有点神秘。所写的查询没有为 JOIN 操作提供任何价值。一般来说,当您想将一个表加入到自身中时,它位于不同的列上:

    select *
    from tbl as a
    inner join
    table as b
    on a.col1 = b.col2
    where 
    a.col1 = 1;
    

    这允许您对表进行查询,并收集在同一个表中以分层方式组织的相关信息。例如:

    create table tbl (
    person_id int,
    parent_id int
    );
    

    在这种情况下,父母也是人。如果您想获取与 ID 为 1 的人相关的父母列表,您可以这样写:

    select
    person.person_id as OriginalPerson,
    parent.person_id as Parent
    from
    tbl as person
    inner join
    tbl as parent
    on parent.person_id = person.person_id
    where
    person.person_id = 1;
    

    更新在阅读您的进一步解释后,您想要一个笛卡尔积:

    select a.*, b.*
    from tbl as a
    inner join tbl as b
    on 1=1
    where a.col1 = 1
    and b.col1 = 1
    

    【讨论】:

    • 这只是返回 tbl 中所有内容与其他所有内容的连接。没有条件。
    • 所以只有 col1 = 1 时才需要它?我以为您只是将其用作被误导的 JOIN 条件。在这种情况下,双 WHERE 子句不是浪费;事实上这是绝对必要的。
    猜你喜欢
    • 2021-11-12
    • 2021-03-28
    • 2015-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多