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

在另一个查询中引用MySQL子选择,mysql,row-number,Mysql,Row Number,我有一个基本的MySQL表terms,由id和term字段组成 我想创建一个按字母顺序排序的字典索引,在字面意义上,它将在所选术语上方列出10个术语,在其下方列出20个术语。这方面的一个例子可以在这里找到,在左边的一栏中,您可以看到当前术语突出显示,它上面的一些术语,下面的一些术语,都按字母顺序排序 众所周知,MySQL不支持行数或类似的函数,因此我们最终求助于用户变量和子选择。我也不能用用户定义的变量创建视图,因为MySQL不允许这样做。以下是我设法想到的,它是有效的: SET

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

我想创建一个按字母顺序排序的字典索引,在字面意义上,它将在所选术语上方列出10个术语,在其下方列出20个术语。这方面的一个例子可以在这里找到,在左边的一栏中,您可以看到当前术语突出显示,它上面的一些术语,下面的一些术语,都按字母顺序排序

众所周知,MySQL不支持行数或类似的函数,因此我们最终求助于用户变量和子选择。我也不能用用户定义的变量创建视图,因为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
第一个选择只需在整个按字母顺序排序的术语表中查找目标术语的行号。第二个选择使用该信息在其上方获取10个术语,在其下方获取20个术语

我想知道是否有办法避免在第二个select查询中运行sub-select,而只引用第一个别名为ordered的查询。有没有一种更有效的方法来实现这一点,而不必手动创建临时表?我做错了什么?

更新:

有关性能详细信息,请参阅我博客中的这篇文章:

如果您的术语已编入索引,则只需运行:

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
,这将更有效。

更新:

有关性能详细信息,请参阅我博客中的这篇文章:

如果您的术语已编入索引,则只需运行:

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

,这样会更有效率。

这确实有效,而且对于我来说更简单、更快。但是,这两个子查询都需要按照MySQL使用别名,并且第一个子查询需要按照ASC顺序排序,这样才能工作。非常感谢。@Salaryman:但第一个子查询必须是DESC,不是吗?它应该选择最后10个小于或等于给定值的值。在这两种情况下,选择的行相同,只是顺序不同。因为我希望所有的东西都按字母升序排列,所以所有的东西都是按字母升序排列的。这也消除了对联合结果进行最终排序的需要,我们只需对子查询而不是对子查询的父SELECT语句进行联合即可。它需要按DESC顺序,我忘记了更改返回行的限制。这确实有效,而且对于我来说更简单、更快。但是,这两个子查询都需要按照MySQL使用别名,并且第一个子查询需要按照ASC顺序排序,这样才能工作。非常感谢。@Salaryman:但第一个子查询必须是DESC,不是吗?它应该选择最后10个小于或等于给定值的值。在这两种情况下,选择的行相同,只是顺序不同。因为我希望所有的东西都按字母升序排列,所以所有的东西都是按字母升序排列的。这也消除了对联合结果进行最终排序的需要,我们只需对子查询而不是对子查询的父SELECT语句进行联合即可。它需要按DESC顺序,我忘记了更改返回行的限制。