从按日期排序的列表中选择下一条记录

时间:2009-03-25 21:24:39

标签: sql mysql

我正在使用此SQL查询在php页面中按日期排序记录列表。

SELECT ARTICLE_NO, USERNAME, ACCESSSTARTS, ARTICLE_NAME FROM table WHERE upper(ARTICLE_NAME) LIKE % x % ORDER BY str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s');

这很好用。

在另一个php页面中,我希望能够删除此记录,并在列表中显示下一个记录。我用来做的查询是:

SELECT ARTICLE_NO FROM auctions1 WHERE str_to_date( ACCESSSTARTS, '%d/%m/%Y %k:%i:%s' ) > (SELECT str_to_date( ACCESSSTARTS, '%d/%m/%Y %k:%i:%s' ) FROM table WHERE ARTICLE_NO =".$pk.") ORDER BY str_to_date( ACCESSSTARTS, '%d/%m/%Y %k:%i:%s' ) LIMIT 1";

我似乎遇到的问题是,因为有许多记录具有相同的日期,所以将选择具有相同日期的记录组中的任何记录,而不是列表中的相同记录。

如何从与第一个查询相同的结果集中选择返回的下一条记录?第一个查询总是返回相同的顺序,所以我不确定为什么第二个查询似乎有不同的顺序。

编辑:

我一直在尝试使用Quassnoi建议。我现在使用的第一个查询是:

SELECT  ARTICLE_NO, USERNAME, ACCESSSTARTS, ARTICLE_NAME,
        date_format(str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), '%d %m %Y' ) AS shortDate
FROM    AUCTIONS1
WHERE   upper(ARTICLE_NAME) LIKE % x %
ORDER BY
        str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), article_no limit 0, 10

Quassnoi建议的第二个查询是:

SELECT  ARTICLE_NO
FROM    auctions1
WHERE   (str_to_date( ACCESSSTARTS, '%d/%m/%Y %k:%i:%s' ), article_no) >
        (
        SELECT  str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), article_no
        FROM    auctions1
        WHERE   ARTICLE_NO = xxx
        )
ORDER BY
        str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), article_no
LIMIT 1

我通过我的php页面回显它来复制这个查询,并简单地放置了xxx代替了存在的article_no。这完全匹配第一个代码示例,但结果与我在原始问题中使用的代码相同。

EDIT2:

这是用于获取原始结果集的查询:

SELECT ARTICLE_NO, USERNAME, ACCESSSTARTS, ARTICLE_NAME, date_format(str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), '%d %m %Y' ) AS shortDate FROM auctions1 WHERE upper(ARTICLE_NAME) LIKE '%o%' ORDER BY str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), article_no limit 0, 10;

这导致了这些数据,这很好:

ARTICLE_NO  USERNAME    ACCESSSTARTS        ARTICLE_NAME                        shortDate
160288212077    5864_australen  30/09/2008 05:22:30     DON ED HARDY TIGER JACKE WEISS   XL             30 09 2008
220288566257    fashionticker1  01/10/2008 16:39:12     Ed Hardy Tank Top Lila Neu & OVP Gr. L          01 10 2008
280273115680    mulle15     01/10/2008 16:42:38     Ed Hardy, T-Shirt,Destroy, schwarz, Gr.L        01 10 2008
280273115991    mulle15     01/10/2008 16:43:54     Ed Hardy, T-Shirt,Destroy, schwarz, Gr.XL       01 10 2008
280273116224    mulle15     01/10/2008 16:44:59     Ed Hardy, T-Shirt,Destroy, schwarz, Gr.XXL      01 10 2008
280273118653    mulle15     01/10/2008 16:54:50     Ed Hardy, T-Shirt,King Snoopy,chocolate, Gr.M       01 10 2008
120312402767    lieschenjuli    01/10/2008 16:56:12     Badehose Shorts Ed Hardy L              01 10 2008
280273119206    mulle15     01/10/2008 16:56:47     Ed Hardy, T-Shirt,King Snoopy,chocolate, Gr.XL      01 10 2008
280273119489    mulle15     01/10/2008 16:57:49     Ed Hardy, T-Shirt,King Snoopy,chocolate, Gr.XXL     01 10 2008
160288777155    bonifatzius1    01/10/2008 16:58:33     Ed Hardy Bomberjacke Gr. L Jacke für Damen oder H...   01 10 2008

问题是,如果我执行此查询:

SELECT  ARTICLE_NO
FROM    auctions1
WHERE   (str_to_date( ACCESSSTARTS, '%d/%m/%Y %k:%i:%s' ), article_no) >
        (
        SELECT  str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), article_no
        FROM    auctions1
        WHERE ARTICLE_NO =160288212077
        )
ORDER BY
        str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), article_no
LIMIT 1;

这将返回280273112610,何时应返回220288566257

3 个答案:

答案 0 :(得分:1)

您也可以尝试通过ARTICLE_NO订购结果。只是做:

... ORDER BY str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), ARTICLE_NO ...

这样,两个结果集应具有完全相同的顺序。在这两种情况下,下一条记录将是具有最低ARTICLE_NO且后期日期的记录。

问候

的Sacher

答案 1 :(得分:1)

SELECT  ARTICLE_NO
FROM    auctions1
WHERE   upper(ARTICLE_NAME) LIKE '% x %'
        AND (str_to_date( ACCESSSTARTS, '%d/%m/%Y %k:%i:%s' ), article_no) >
        (
        SELECT  str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), article_no
        FROM    auctions1
        WHERE   ARTICLE_NO = @pk
        )
ORDER BY
        str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), article_no
LIMIT 1

请注意您的原始结果集:

SELECT  ARTICLE_NO, USERNAME, ACCESSSTARTS, ARTICLE_NAME
FROM    auctions1
WHERE   upper(ARTICLE_NAME) LIKE % x %
ORDER BY
        str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s');

不保证在一个ACCESSSTARTS内保持稳定的行顺序。您需要将PRIMARY KEY添加到ORDER BY子句中,如下所示:

SELECT  ARTICLE_NO, USERNAME, ACCESSSTARTS, ARTICLE_NAME
FROM    auctions1
WHERE   upper(ARTICLE_NAME) LIKE % x %
ORDER BY
        str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s'), article_no.

(我假设ARTICLE_NO是你桌子的PRIMARY KEY

您的原始行集取决于它使用的访问方法,按索引顺序以表顺序返回行。

您确实需要更改原始行集以使用稳定订单。

但是如果由于某种原因你不能这样做,你可以做到以下几点:

SELECT  ARTICLE_NO, USERNAME, ACCESSSTARTS, ARTICLE_NAME,
FROM    (
        SELECT  @c := NULL
        ) vars,
        auctions1
WHERE   upper(ARTICLE_NAME) LIKE % x %
        AND CASE WHEN ARTICLE_NO = $PK THEN @с := 0 ELSE 0 END IS NOT NULL
        AND (@c := @c + 1) = 2
ORDER BY
        str_to_date(ACCESSSTARTS, '%d/%m/%Y %k:%i:%s');
LIMIT 1

此查询的效率较低,并且很大程度上依赖于此查询将使用与原始查询完全相同的访问方法。

您通常不会依赖此事实,因为访问方法可以随时更改。

如果您想要清晰明了的代码,只需将ARTICLE_NO添加到ORDER BY并享受我首先发布的查询。

答案 2 :(得分:0)

这是完全逻辑的。您在第一个查询中的第二个查询中缺少ARTICLE_NAME的条件 - 第二个查询返回的行数多于第一个查询的行数。删除LIMIT,你会看到。第二个排序条件也是一个好主意,即使数字是任意的。