ほんの数時間前、 このトピックに関するコメントを注意深く調べた後、多くの人がHAVING条件の使用をあまり好まないことに驚き、他のDBMS機能のように見えます。 率直に言って、私は最も単純で機能しない要求の議論が本当に好きでした。その結果、多くの人が多くの新しい有益なことを学びました(これは私の個人的な意見です)。 そこで、私はこれを行うことにしました。お気に入りの3つのSQL(MySQL)タスクを公開します。
これらのタスクは絶対に現実的であり、遠い明るい過去に実際に行われ、一定の作業時間と神経細胞の犠牲者によって首尾よく解決されました。 私はそれらがこの日に関連していること、そして長期間関連することを100%確信しています。 それらを複雑と呼ぶことはできませんが、非常に単純でもあります(もちろん、トレーニングのレベルによって異なります)。
だから...正直なところ、誰がそれらを解決するのかを知りたいと思っています。 もちろん、解決策はありますが、SQLのプロがどのように決定するかを知ることは私の利己的な関心であることを認めています。 はい、そして誰もが興味を持っているでしょう、私は思う...一言で-私は本当にkamentyが支配したいと思います。 :-)
状態。
画像ギャラリーは3つのシンプルなテーブルで構成されています。 特定の数のカテゴリがあり、各カテゴリには特定の数のフォトアルバムが含まれ、その中にはYa Leftサイクルの写真の雲が含まれます。 たまたま、既存の構造を変更することはできません(そう、それは面白くないでしょう)。
--
CREATE TABLE `photo_category` (
`id` int (11) NOT NULL AUTO_INCREMENT,
`title` varchar (255), --
`is_published` tinyint(1), -- 1/0 - /
`ordi` int (11), -- , 1 ...
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
--
CREATE TABLE `photo_gallery` (
`id` int (11) NOT NULL AUTO_INCREMENT,
`c_id` int (11), -- ID
`title` varchar (255), --
`is_published` tinyint(1), -- 1/0 - /
`ordi` int (11), -- , 1 ...
PRIMARY KEY (`id`),
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
--
CREATE TABLE `photo_image` (
`id` int (11) NOT NULL AUTO_INCREMENT,
`g_id` int (11), -- ID
`title` varchar (255), -- ( )
`is_published` tinyint(1), -- 1/0 - /
`is_main_foto` tinyint(1), -- 1/0 - /.
`ordi` int (11) DEFAULT NULL , -- , 1 ...
PRIMARY KEY (`id`),
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
* This source code was highlighted with Source Code Highlighter .
すべてのタスクに適用される条件:
1)is_publishedフラグは、オブジェクト自体とそれに含まれるすべてのオブジェクトを除外する必要があります。 つまり、カテゴリis_published = 0の場合、すべてのアルバムとそれに応じてすべての写真を除外する必要があります(さらに、公開されているかどうかはすでに気にしません)。
2)すべてのソート条件は、ordiキー上になければなりません。
3)すべてのタスクについて、空のギャラリーとカテゴリ、つまり、ギャラリーがないカテゴリとカテゴリがないギャラリーを表示することはできません。
4)ギャラリーでは、メインまたはなしとしてマークできる写真は1つだけです。 そのような写真がis_published = 0であっても表示されます。それに加えて、is_published = 1の写真がまだある場合
5)追加します-条件は戦闘です。つまり、すべてのリクエストはできるだけシンプルで、できるだけ早く動作する必要があり、リクエストの数は最小限に抑える必要があります。
はい、些細なことに気を取られないように、重要でないフィールドとインデックスを意図的にテーブルから除外しました:-)
そして今、タスク自体(昇順の複雑さで):
タスク1
指定されたカテゴリID。 リクエストを書く必要があります(1つ!)このカテゴリのすべてのギャラリーを受け取る必要があります。各ギャラリーは、メインの写真のIDを受け取り、もしなければ、カテゴリ内の誰かのIDを受け取ります(とにかく、写真がある場合のみ)。
タスク2
与えられたID foty。 必要に応じて-同じギャラリーID。 ordiに従って順番に次/前の写真を決定するのに最小限の労力が必要です。 (次/前の決定はis_published = 0になる可能性があるため、ordiのみで決定を下すことは不可能であるため、is_published = 1の最も近いものを選択する必要があります)。 この問題は2つのリクエストで解決され、1つ(UNIONなし)で解決できると確信していますが、成功しませんでした。 誰かが敬意と敬意で成功した場合。 :-)
タスク3
これは最も小さいです。 特定の数Nを指定します。カテゴリとその中の最近のアルバムの数をリストする必要があります。各カテゴリについて、この数はNを超えてはならず、ordiで降順にソートする必要があります。 つまり、最初の10枚の写真、2枚目の25枚、3枚目の3枚の3つのカテゴリについて考えてみましょう。 出力は、最初の5つが最後(最大のordiが降順でソート)、2つ目が5(類似)、3つ目が3-3(類似)である必要があります。 さらに、最初のタスクの条件、つまり、ギャラリーまたは他のいくつかのメイン写真が必要です。
私は3つの問題すべてに対する解決策を持っています。それらを間違いなく公開しますが...後で、そして何を、どのように、そしてなぜ説明します。 :-)それでも-多くの人にとって、一見すると、これは信じられないほど複雑に思えます-実際、ソリューションは非常に単純ですが、有名なHAVINGなどの「まれに使用される」(一部の)SQL構造が含まれています。
DBMS-MySQL 5.ストアドプロシージャと関数なしで実行します。 頑張って :-)
UPD:ソリューションはこちらです。 そこで、トピック全体に対してタイプされましたが、私はそれをしました。