ソートタスク

おそらく、このタスクは一部の人にはささいなことのように思えるかもしれませんが、私は個人的に数時間を費やし、「聴衆の意見」と「友人を呼ぶ」というプロンプトを費やしました。 なぜこれを決めたのですか? 答えは簡単です。小さなWebサイトOdio.ruにこのアプローチを実装する必要がありました。 要するに、RSSによってプルされたさまざまなサイトから公開された投稿があります。 難点は、これらのレコードの日付が完全に一致する可能性があることです(同じテープ内でも)。IDシ​​ーケンスは同じテープ内でのみ意味があり、レコードのストリーム全体には影響しません。 それでは、問題の条件に移りましょう。

これはMySQLに関するブログなので、タスクのテストテーブルにSHOW CREATE TABLEをすぐに提供します。

CREATE TABLE `test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`date` datetime NOT NULL,
`content` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `date` (`date`)
) ENGINE=MyISAM;


次に、テストデータを入力します。

INSERT INTO `test` (`id` ,`date` ,`content`)
VALUES (NULL , '2010-03-01 11:00:00', 'Test 1'),
(NULL , '2010-03-01 12:00:00', 'Test 2'),
(NULL , '2010-03-01 13:00:00', 'Test 4'),
(NULL , '2010-03-01 12:00:00', 'Test 3'),
(NULL , '2010-03-01 14:00:00', 'Test 5');


その結果、次のテーブルを取得します( SELECT * FROM `test` ORDER BY `id` ):

| 1 | 2010-03-01 11:00:00 | Test 1 |
| 2 | 2010-03-01 12:00:00 | Test 2 |
| 3 | 2010-03-01 13:00:00 | Test 4 |
| 4 | 2010-03-01 12:00:00 | Test 3 |
| 5 | 2010-03-01 14:00:00 | Test 5 |


ご覧のとおり、テーブルはIDでソートされ、日付の順序は間違っています。

さて、実際には、タスク自体:入力にレコードの1つがあります(つまり、IDとDATEがわかっています)。 隣接するレコード (前と次) のIDを取得する必要があります 。一方、DATEが一致すると、前のレコードのIDは次のものにはもっとあります。

観察者の読者は、(前のエントリに対して)単純に行うと、次のことをすぐに理解できSELECT `id` FROM `test` WHERE `date` <= $date AND `id` != $id ORDER BY `date` DESC, `id` DESC LIMIT 1 、レコード2と4が同じDATEであるため、レコード2と4を「ループ」します。つまり、2は4の前のもので、4は2の前のものです。隣人として(それぞれ、1の前のものと5の次のもの)何も返されませんでした。

簡単にするために、前のエントリのみを見てみましょう。 5番目のレコードから開始し、ID = 5およびDATE = '2010-03-01 14:00:00'を持っています。 レコード3を取得する必要があります。次に、条件ID = 3およびDATE = '2010-03-01 13:00:00'のように取得します...

この問題には少なくとも1つの解決策があります。)1つのリクエストは1つの前のレコードであり、他のパラメーターを持つ同じリクエストは次の前のレコードです。 つまり、「すべてを取得してそれを実行する」オプションは適切ではありません。 また、「新しいレコードを追加するときに、ORDER_NUM列を追加し、テーブル全体に対して再構築する」オプションは適切ではありません。 「既に表示されているレコードのレコードIDを選択から除外する」オプションは適切ではなくなりました。

一般に、現在のレコードのIDとDATEによって、この前のレコードの実際のIDを返す「正直な」リクエストが必要です。

コメントの不必要な炎を避けるために、私はすぐに答えます。はい、私は自分のサイトのアドレスへのリンクを意図的に投稿しました。これはこの問題の応用の実例だからです。 もちろん、他のサイトと同様に、彼はもっと頻繁に訪問したいと思っています;)

また、私が思いついたものよりも良いことが判明した場合、私はあなたの要求を使用する権利を留保します;)当然、あなたの許可で...

問題の状況で何かはっきりしないことがあれば、コメントで明確にしたいと思います。

そして、書く必要はありません:「どんなナンセンス? %framework_name%を使用し、彼はあなたのためにすべてを行います... "-私は興味がありません、MySQLブログ、MySQLでタスクをソートするので、MySQL内ですべてを行います。

UPDATE見つかった1つのソリューション:

SELECT `id`
FROM `test`
WHERE `date` < $date or (`date` = $date and `id` < $id)
ORDER BY `date` DESC, `id` DESC LIMIT 1


によって提出されましたSabMakc

おそらく提示されているよりも複雑な他のソリューションがありますが、それでも検索を続けることができます...

更新2この問題に対する「複雑な」3階建てのソリューションを提供します。

SELECT `id`, `date`, IF (`date` = $date AND id < $id, 0, 1) AS `ordr`
FROM `test`
WHERE `date` <= $date AND `id` != $id
HAVING `date` < IF (`ordr` = 1, $date, NOW())
ORDER BY `ordr`, `date` DESC, `id` DESC
LIMIT 1


これが私の決定です。 実際、以前のSabMakcソリューションと同じですが、他のゲートを少し通って...

Source: https://habr.com/ru/post/J85945/


All Articles