0

私は2つのテーブルを持っています:newsnews_filesnewsテーブルには、と他のnewsIdいくつかの列がnews_files含まれnewsId、とが含まれますfilePath。レコードの場合、news少なくとも5つのファイルを持つことができます。

newsこの特定のレコードのすべての列とすべてのファイルを、news重複することなく1つのクエリで取得するための最良のソリューションは何でしょうか。

これまでに次のクエリがありますが、それぞれに対して同じレコードnews_filesが返されます(同じレコードごとにnews1行)。filePathnews

select n.* from news n 
left outer join news_files nf on n.Id = nf.newsid 
where n.Id = 1
4

2 に答える 2

1

newsのような1対多の関係の場合news_files、それらすべてを1つのクエリにまとめるには、ご存知のとおり、「多」テーブルの関連する行ごとに「1」から重複する列値を取得する必要があります。

ただし、これを1つのクエリで実行する必要があるかどうかは疑問です。news_files1対1の関係の場合、行ごとに1つの行しかない場合はnews、1つのクエリでそれらを生成しようとするのが理にかなっています。ただし、1対多の場合は、メインテーブルをクエリしてから、「多くの」関係テーブルから関連する行をクエリすることもできます。

/* Returns duplicate column values for each news_files row */
/* and all columns from both tables */
SELECT
  n.*,
  nf.*
FROM 
  news n
  LEFT OUTER JOIN news_files nf ON n.Id = nf.newsid
WHERE n.Id = 1

ただし、を使用して1つの列をnews_filesカンマ区切りのリストとして取得できますGROUP_CONCAT()が、これはすべての行を取得することとまったく同じではありません。MySQLでは、に表示されていない列をGROUP BYリストに含めることができますがSELECT、他のRDBMSでは許可されていないため、移植性のために、GROUP_CONCAT()はサブクエリに配置され、メインテーブルに対して結合してすべての列を取得します。

/* Comma-separated list of filePath and all cols from news */
SELECT 
  n.*,
  nf.files
FROM
  news 
  LEFT OUTER JOIN (
    SELECT newsid, GROUP_CONCAT(filePath) AS files FROM news_feeds
    GROUP BY newsid
  ) nf ON n.Id = nf.newsid
于 2012-04-08T23:46:48.257 に答える
0

これは、ニュースに2つの列があり、news_filesに2つの列があることを前提としています...必要に応じてnullを埋め込みます。

select n.Id, n.someothercolumn, null as newsId, null as filepath
from news n
where Id = 1

union

select null, null, nf.newsId, nf.filepath
from new_files nf
where newedId = 1

order by isnull(Id, newsId)

最もエレガントではありませんが、すばやく汚れたものが必要な場合は機能するはずです!

于 2012-04-09T03:33:40.287 に答える