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记录) - 所以我认为性能不是一件值得关注的事情。
问题
我的查询能以某种方式简化吗?此外,重要的是不要使用变量。订单可以包含在结果中(比如我的小提琴) - 但这不是强制性的。
答案 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列,不确定我的查询是否错误。