выбор следующей записи из списка, упорядоченного по дате - PullRequest
2 голосов
/ 26 марта 2009

Я использую этот 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 ]

1 голос
/ 26 марта 2009
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 и наслаждайтесь запросом, который я отправил первым.

1 голос
/ 26 марта 2009

Вы также можете попробовать упорядочить результаты по ARTICLE_NO. Просто сделай:

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

Таким образом, оба набора результатов должны иметь одинаковый порядок. В обоих случаях следующей записью будет запись с наименьшим ARTICLE_NO с последующей датой.

Привет

Sacher

0 голосов
/ 26 марта 2009

Это совершенно логично. У вас есть условие для ARTICLE_NAME в первом запросе, которое отсутствует во втором запросе - второй запрос возвращает больше строк, чем первый. Снимите ПРЕДЕЛ, и вы увидите. Второе условие упорядочения также является хорошей идеей, даже если число произвольно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...