2

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

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
4

2 回答 2

2

您基本上是在要求有意的笛卡尔连接

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 列排序

于 2012-03-08T02:46:08.147 回答
0

我真的建议避免使用 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
于 2012-03-08T01:56:29.897 回答