对于压缩的SQL习惯用语是什么 - 在功能意义上 - 两个查询?

时间:2013-08-25 18:30:01

标签: mysql 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 ...但可能 - 乐观? - 有合理的标准兼容方式吗?

2 个答案:

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