无需两个查询就连接表

时间:2012-03-08 01:46:07

标签: mysql sql join cross-join

我看到人们建议通过这样做来交叉加入桌子:

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

2 个答案:

答案 0 :(得分: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列

的顺序

答案 1 :(得分: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