2

例如,如果我有一组班级和一组教室,并且我想通过任意配对将两者配对:

> 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 ......但可能 - 乐观?— 是否有合理的符合标准的方法来做到这一点?

4

2 回答 2

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 | 房间名称 |
-------------|------------|
| 微积分 | 101 室 |
| 英语 | 102 室 |
| 历史 | 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演示

于 2013-08-25T18:37:46.653 回答
1

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

因此,您可以通过使用变量来枚举行,然后使用union allandgroup 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;
于 2013-08-25T18:38:47.223 回答