2013-08-25 20 views
2

举例来说,如果我有一组类和一组教室,我要配对两个了一些任意配对:什么是压缩的SQL语言 - 在功能上 - 两个查询?

> SELECT class_name FROM classes ORDER BY class_name 
Calculus 
English 
History 
> SELECT room_name FROM classrooms ORDER BY room_name 
Room 101 
Room 102 
Room 201 

我想“拉链”他们是这样的:

> SELECT class_name FROM classes ORDER … ZIP SELECT room_name FROM classrooms ORDER … 
Calculus | Room 101 
English | Room 102 
History | Room 201 

目前我正在处理MySQL ...但可能 - 乐观? - 有一个合理的标准兼容方式来做到这一点?

+1

它看起来像一个加入,但它通过什么标准并不清楚。 – JJJ

+0

目前我正在处理MySQL,但我想知道是否有任何通用的方法来做到这一点(因为我一般处理PostgreSQL,偶尔也处理SQLite)。 –

+1

您必须在两个表之间使用[join](http://en.wikipedia.org/wiki/Join_%28SQL%29)在多个表上使用查询。 – JimmyB

回答

3

一种方式做到这一点在MySQL

SELECT c.class_name, r.room_name 
    FROM 
(
    SELECT class_name, @n := @n + 1 rnum 
    FROM classes CROSS JOIN (SELECT @n := 0) i 
    ORDER BY class_name 
) c JOIN 
(
    SELECT room_name, @m := @m + 1 rnum 
    FROM classrooms CROSS JOIN (SELECT @m := 0) i 
    ORDER BY room_name 
) r 
    ON c.rnum = r.rnum 

输出:

 
| CLASS_NAME | ROOM_NAME | 
-------------|-----------| 
| Calculus | Room 101 | 
| English | Room 102 | 
| History | Room 201 | 

这里是SQLFIddle演示


Postgres里同样的事情会像

SELECT c.class_name, r.room_name 
    FROM 
(
    SELECT class_name, 
     ROW_NUMBER() OVER (ORDER BY class_name) rnum 
    FROM classes 
) c JOIN 
(
    SELECT room_name, 
     ROW_NUMBER() OVER (ORDER BY room_name) rnum 
    FROM classrooms 
) r 
    ON c.rnum = r.rnum 

这里是SQLFiddle演示


而且在SQLite的

SELECT c.class_name, r.room_name 
    FROM 
(
    SELECT class_name, 
     (SELECT COUNT(*) 
      FROM classes 
      WHERE c.class_name >= class_name) rnum 
    FROM classes c 
) c JOIN 
(
    SELECT room_name, 
     (SELECT COUNT(*) 
      FROM classrooms 
      WHERE r.room_name >= room_name) rnum 
    FROM classrooms r 
) r 
    ON c.rnum = r.rnum 

这里是SQLFiddle演示

1

这是join一种形式,但你需要创建连接密钥。唉,但是,这需要full outer join,因为你不知道哪个列表更长。

所以,你可以通过使用变量来枚举行,然后使用union allgroup by得到的值做到这一点:

select max(case when which = 'class' then name end) as class_name, 
     max(case when which = 'room' then name end) as room_name 
from ((SELECT class_name as name, @rnc := @rnc + 1 as rn, 'class' as which 
     FROM classes cross join 
      (select @rnc := 0) const 
     ORDER BY class_name 
    ) union all 
     (select room_name, @rnr := @rnr + 1 as rn, 'room' 
     from classrooms cross join 
      (select @rnr := 0) const 
     ORDER BY room_name 
    ) 
    ) t 
group by rn;