在MySQL中反向加入

时间:2013-10-01 10:51:41

标签: mysql sql join sql-order-by

SO,

问题

我的问题是 - 如何以相反的顺序将MySQL中的表连接起来?假设我有:

id  name
1   First
2   Second
5   Third
6   Fourth
7   Fifth
8   Sixth
9   Seventh
13  Eight
14  Nine
15  Tenth

- 现在我想创建一个查询,它将以相反的顺序返回连接的记录:

left_id name    right_id    name 
   1    First      15   Tenth 
   2    Second     14   Nine 
   5    Third      13   Eight 
   6    Fourth      9   Seventh 
   7    Fifth       8   Sixth 
   8    Sixth       7   Fifth 
   9    Seventh     6   Fourth 
  13    Eight       5   Third 
  14    Nine        2   Second 
  15    Tenth       1   First 

我的方法

我现在有了这个问题:

SELECT 
  l.id AS left_id, 
  l.name, 
  (SELECT COUNT(1) FROM sequences WHERE id<=left_id) AS left_order, 
  r.id AS right_id,
  r.name,
  (SELECT COUNT(1) FROM sequences WHERE id<=right_id) AS right_order 
FROM 
  sequences AS l 
  LEFT JOIN 
    sequences AS r ON 1
HAVING
  left_order+right_order=(1+(SELECT COUNT(1) FROM sequences));

- 请参阅此fiddle了解样本结构&amp;代码。

一些背景

没有用例。我以前在应用程序中这样做。现在,如果有一种方法可以在SQL中实现这一点,那就是好奇心 - 这就是为什么我不仅仅寻求'任何解决方案'(就像我的) - 而是尽可能简单的解决方案。源表总是很小(<10.000记录) - 所以我认为性能不是一件值得关注的事情。

问题

我的查询能以某种方式简化吗?此外,重要的是不要使用变量。订单可以包含在结果中(比如我的小提琴) - 但这不是强制性的。

3 个答案:

答案 0 :(得分:2)

我唯一可以考虑改进的是

SELECT 
  l.id AS left_id, 
  l.name ln, 
  (SELECT COUNT(1) FROM sequences WHERE id<=left_id) AS left_order, 
  r.id AS right_id,
  r.name rn,
  (SELECT COUNT(1) FROM sequences WHERE id>=right_id) AS right_order 
FROM 
  sequences AS l 
  LEFT JOIN 
    sequences AS r ON 1
HAVING
  left_order=right_order;

有两个变化可以让它更快一点:

1)首先以相反的顺序计算正确的顺序

2)避免在最后一行使用SELECT COUNT

编辑:我别名ln,因为我看不到小提琴中的列

答案 1 :(得分:1)

如果没有SQL standard RANK() OVER(...),您必须在发现时自行计算排序。

行的RANK()只是1 +所有排名较好的行的COUNT()。 (DENSE_RANK(),为了比较,是1 +所有DISTINCT更好等级的COUNT()。)虽然RANK()可以在SELECT投影中计算为标量子查询 - 例如,你已经完成{{1}我倾向于喜欢加入:

SELECT (SELECT COUNT(1) ...), ...

答案 2 :(得分:0)

SET @rank1=0;
SET @rank2=0;

SELECT *
FROM (SELECT *, @rank1 := @rank1 + 1 AS row_number FROM sequences ORDER BY ID ASC) t1
INNER JOIN (SELECT *, @rank2 := @rank2 + 1 AS row_number FROM sequences ORDER BY ID DESC) t2
on t1.row_number = t2.row_number

出于某种原因,sql fiddler确实只显示了3列,不确定我的查询是否错误。