如何从查询结果中过滤邻居行(第一,上一个,下一个,最后一个)?

时间:2019-04-14 06:21:47

标签: subquery mysql-5.5

我正在为大量记录开发快速链接解决方案。记录按用户排序(此处不相关的条件),并且我已经建立了ID列表。现在,我设法为每个ID添加一个职位。

SELECT
     cp.id,
     cp.page_name,
     @rownum := @rownum + 1 AS `position`
FROM couch_pages cp
JOIN (SELECT @rownum := 0) r
WHERE cp.template_id = '2'
ORDER BY cp.publish_date DESC

couch_pages具有idtemplate_idpage_namepublish_date和许多其他列。客户端可以请求ID的任意顺序。我必须跟随领导并重新计算位置。

我不知道的是,不仅可以计算整个集合的位置,还可以计算任意ID的位置,例如cp.id = '1600'并接收prev-next-last-first在单个查询中记录。

上面查询的结果看起来很简单-

"id"    "page_name" "position"

"1578"   "late-in-the-evening"  "1"
"1600"   "thats-why-god-made-"  "2"
"1599"   "god-bless-the-absen"  "3"
............................
"124601" "loves-me-like-a-ro"   "122703"

此刻,我将整个结果发送到PHP数组,并能够找到匹配的记录(例如,id为“ 1600”)及其邻居-上一条记录(id =“ 1578”),下一条记录,第一个和最后一个记录。

我不想将整个子集发送给客户端,因为我预计记录数量会爆炸并且脚本会变慢。

是否可以从结果中过滤给定ID的必需(上一个,下一个,最后一个,第一个)记录?

1 个答案:

答案 0 :(得分:0)

使用Cross JOIN为您的记录创建了一个新列,以确定哪个是第一个记录,哪个是最后一个记录。如我的第一条评论所述,count(*)就足够了,因为我们可以根据position列进行检查。

  

在MySQL中,JOIN, CROSS JOIN 和INNER JOIN是语法等效项(它们可以相互替换)。在标准SQL中,它们不是等效的。 INNER JOIN与ON子句一起使用,否则使用CROSS JOIN

尝试以下代码:

    SELECT
    a.*,
    (
    CASE

            WHEN a.position = 1 
            AND a.position = c.total_records THEN
                3 -- Mark only if you have one record 3 = (1 and 2) at the same time

                WHEN a.position = 1 THEN
                1 -- Mark first record with 1

                WHEN a.position = c.total_records THEN
                2 -- Mark last record with 2
                ELSE 0 
            END 
            ) AS row_status 
        FROM
            ( SELECT count( * ) AS total_records FROM couch_pages ) c
            CROSS JOIN (
            SELECT
                x.id,
                x.page_name,
                x.position 
            FROM
                (
                SELECT
                    t.id,
                    t.page_name,
                    @rownum := @rownum + 1 AS position 
                FROM
                    couch_pages t
                    JOIN ( SELECT @rownum := 0 ) r 
                -- ORDER BY
                    -- cast( SUBSTR( t.page_name, 5 ) AS INT ) -- Order by the INT part of your page_name

                ) x 
            ) a 
    LIMIT 4 OFFSET 3;-- This is the line you should adjust using PHP, you can keep the values in POST or GET like FQDN/?page=3&records_per_page=4