在另一个查询中引用MySQL子选择

时间:2009-07-17 17:09:33

标签: mysql row-number

我有一个基本的MySQL表, terms ,由 id term 字段组成。

我想创建按字母顺序排序的字典索引(在字面意义上),它会在所选术语上方列出10个术语,在其下面列出20个术语。可以在此处找到此示例[{3}},您可以在左栏中看到当前字词突出显示,以及上面的一些字词,以及下面的一些字词,按字母顺序排序。

众所周知,MySQL不支持ROW_NUMBER()或类似功能,因此我们最终会求助于用户变量和子选择。我也无法用用户定义的变量创建一个View,因为MySQL不允许这样做。这就是我设法提出的(并且有效):

        SET @row_num := 0;

        SELECT
             @term_index := ordered.row_number
        FROM 
        (
            SELECT
                 @row_num := @row_num + 1 AS row_number, terms.*
            FROM
                terms
            ORDER BY
                term ASC
        ) AS ordered 
        WHERE
            ordered.term = 'example term';

        SET @row_num := 0;

        SELECT *
        FROM 
        (
            SELECT
                @row_num := @row_num + 1 AS row_number, terms.*
            FROM
                terms
            ORDER BY
                term ASC
        ) AS ordered
        WHERE
             row_number BETWEEN @term_index - 10 AND @term_index + 20

第一个SELECT只是在整个按字母顺序排序的术语表中找出目标术语的行号。第二个SELECT使用该信息获得高于它的10个术语和低于它的20个术语。

我想知道是否有办法避免在第二个SELECT查询中运行子选择,而只是引用第一个别名 ordered 。是否有更有效的方法来实现这一点,而无需手动创建临时表?我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

<强>更新

请参阅我的博客中有关效果详情的文章:


如果您的term已编入索引,则可以运行:

SELECT  *
FROM    (
        SELECT  *
        FROM    terms
        WHERE   term <= @myterm
        ORDER BY
                term DESC
        LIMIT 10
        ) q
UNION ALL
SELECT  *
FROM    (
        SELECT  *
        FROM    terms
        WHERE   term > @myterm
        ORDER BY
                term
        LIMIT 20
        ) q
ORDER BY
        term

,这将更有效。