0

私は2つのテーブルを持っています:

CREATE TABLE `categories` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`asset_id` int(10) unsigned NOT NULL DEFAULT '0',
`title` mediumtext NOT NULL,
`published` tinyint
)

CREATE TABLE `content` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`asset_id` int(10) unsigned NOT NULL DEFAULT '0',
`title` mediumtext NOT NULL,
`catid` int(10) unsigned NOT NULL DEFAULT '0'
)

コンテンツ テーブルの 'catid' には、このコンテンツが属するカテゴリも格納されています (つまり、カテゴリ テーブルの 'id')。次に、'有効な' アセット (カテゴリとコンテンツの両方) のリストを抽出します。次のクエリを使用して、すべての「公開」カテゴリとその中のコンテンツを一覧表示します。

SELECT asset_id, title 
FROM (SELECT asset_id, title FROM categories WHERE published=1) AS ca 
     UNION ALL 
     (SELECT asset_id, title FROM content WHERE catid IN
             (select id FROM categories WHERE published = 1)
     )

私は望ましい結果を得ることができます。ただし、クエリでFROM categories WHERE published = 1が繰り返されていることがわかります (実際の場合、条件は単なる よりもはるかに長くなりますpublished = 1)。それを行うより良い方法はありますか?

私のアセットには「カテゴリ」内の「コンテンツ」内に「画像」が含まれているため、各サブクエリで一連の条件全体を繰り返す必要がありますUNION ALL。クエリをデバッグするのは地獄のようです。

select id, asset_id, title from categories ... AS ca2番目のサブクエリのセットとして「id」列を抽出して抽出する方法があるかどうかを考えていますFROM content WHERE id IN ca.id(もちろん、これは機能していません)。「WITH」を試しましたが、Mysql はサポートしていません。どうもありがとうございました。

4

2 に答える 2

1

JOIN解決策はおそらく最善の方法です...

...しかし、サブクエリ構文を維持したい場合(たとえば、読みやすくするために)、再編成してみませんか?

私がよく理解している場合、「published=1」を持つすべてのカテゴリと、そのカテゴリに属する​​すべてのコンテンツが必要です ( によるとasset_id)。したがって、次のクエリはほぼ同じ結果を生成するはずです (列が 1 つ増えます)。

SELECT asset_id, title 
FROM (SELECT asset_id, title, id FROM categories 
      UNION ALL 
      SELECT asset_id, title, catid FROM content
     ) AS s
     WHERE s.id IN (select id FROM categories WHERE published = 1)

SOに直接入力したことに注意してください。タイプミスやその他の構文エラーをお許しください...

パフォーマンスの観点からは、一時テーブルとファイルソートが必要になるので、これはおそらくあまり良くありません。UNIONしかし、2つのテーブルが必要なため、その点で結合のパフォーマンスが向上するかどうかはわかりません...


何らかの理由でテーブルを 2 回調べるのはコストがかかりすぎて、予想される結果が比較的小さい場合は、クエリの中間結果を保持するために一時テーブル/ビューを使用できます (使用したい場合もあります)。categoriesENGINE MEMORY

これが元のクエリよりも効率的かどうかを判断するのは非常に困難です。これは多くの要因に依存します。とにかく、JOIN今回は次のように使用します。

CREATE TEMPORARY TABLE cache ENGINE MEMORY
 AS SELECT categories.asset_id as cat_aid, categories.title AS cat_t, categories.id AS cat_i,
       content.asset_id as con_aid, content.title AS con_t, content.catid AS con_i
  FROM categories
  LEFT JOIN content
  ON content.catid = categories.id
  WHERE categories.published = 1;

目的の結果を取得することはSELECT ... UNION ...、そのテーブルの問題です。

SELECT DISTINCT cat_aid, cat_t FROM cache
UNION ALL SELECT DISTINCT con_aid, con_t FROM cache;

http://sqlfiddle.com/#!2/32ee4/2を参照してください。

于 2013-08-14T08:52:14.763 に答える
0

それを試してください:

SELECT asset_id, title 
FROM  categories WHERE published=1
    UNION ALL 
SELECT co.asset_id, co.title FROM content co
left join categories  ca
on co.catid = ca.id 
WHERE ca.published =1;

sqlfiddle.com でいくつかの簡単なデータを提供する必要があります。インデックス/PK/FKなどがあるかどうかも質問です...

于 2013-08-14T08:38:02.033 に答える