News
|NewsId|NewsTitle |
|1 |テストニュース|
NewsCategory(連関エンティティ)
|NewsCategoryId|NewsId|CategoryId|
|1 |1 |1 |
|2 |1 |2 |
Category
|CategoryId|CategoryName|
|1 |医療 |
|2 |経済 |
このテーブル構造で、
「医療」カテゴリーと「経済」カテゴリーの両方が設定されている、
ニュースの一覧を取得するSQLはどういったものがあるでしょうか。
SELECT News.* FROM News WHERE News.NewsId IN ( SELECT NewsId FROM NewsCategory JOIN Category USING ( CategoryId ) WHERE NewsCategory.NewsId = News.NewsId AND CategoryName IN ( '医療', '経済' ) GROUP BY NewsId HAVING COUNT(*) = 2 ) ORDER BY News.NewsId
SELECT * FROM NewsCategory
WHERE CategoryId in (1,2)
Categoryのテーブルがありますが、それから「医療」カテゴリーと「経済」カテゴリーを
抽出する条件が記載されていないため、それぞれ固定値にしました。
たとえば
CategoryName = '医療'
というような 条件で抽出するというならば、それでやりますが
普通に考えると 名称を条件に抽出は しませんから。
抽出した結果で 名称を 表示させる場合は、あります。
今回は、取得するには ? でしたので 書きませんでしたが・・・。
今回の場合はCategoryName = '医療'です。
私の書き方が分かりにくかったです。
こんな感じだと思います。
select N.* from News as N where NewsId in(select NewsId from NewsCategory as NC inner join Category as C on NC.CategoryID=C.CategoryID where N.NewsId=NC.NewsId and CategoryName in('医療','経済') group by NewsId having count(distinct CategoryName)=2) order by N.NewsId
ありがとうございます。
おかげで実装できました。
GROUP化とCOUNTを使うアプローチ以外のものも、
もしあればお願いします。
ジョインする方法は、より思い付きやすい方法だと思います。
select N.* from News as N, (select NewsId from NewsCategory as NC inner join Category as C on NC.CategoryID=C.CategoryID where CategoryName='医療') as x, (select NewsId from NewsCategory as NC inner join Category as C on NC.CategoryID=C.CategoryID where CategoryName='経済') as y where N.NewsId=x.NewsId and x.NewsId=y.NewsId
なるほど。
この手もありますね。
確かにGROUP化+COUNTよりも、
直感的な考え方だと思います。
検索条件に選択されたカテゴリーの数が増えると、
最終的に出力されるSQLがやたら長くはなりそうですが。
ありがとうございます。
おかげで実装できました。
GROUP化とCOUNTを使うアプローチ以外のものも、
もしあればお願いします。