0

次のフィールドを持つ単一のテーブル ( と呼ばれるdocuments) で作業しています: idparent_id、およびstatus。フィールドは、同じテーブル内のparent_idフィールドを参照します。フィールドのタイプはidです。statusENUM('submitted', 'accepted', 'rejected')

documentsを持たないものをすべて選択したいと思いますstatus = 'accepted'

私の最初の試みは次のようになりました:

SELECT DISTINCT `documents`.*
FROM (`documents`)
LEFT OUTER JOIN `documents` children_documents
  ON `documents`.`id` = `children_documents`.`parent_id`
WHERE `children_documents`.`id` IS NULL
  OR `children_documents`.`status` != 'accepted'

これに関する問題は、承認された子と承認されていない子の両方を含むドキュメントが引き続き選択されることです。承認された子を持つドキュメントは選択しないでください。

GROUP BY私は私の友人かもしれないと感じていますが、意図した結果を得るためにそれをどのように使用するかわかりません.

4

4 に答える 4

2

私があなたが探しているものを正しく理解しているなら、私は物事を単純にするために次のアプローチを使用します。

SELECT *
FROM `documents`
WHERE `id` NOT IN ( 
    SELECT `parent_id`
    FROM `documents` children_documents
    WHERE `status` = 'accepted' );
于 2012-08-23T02:02:06.307 に答える
2

これをMySQLCASEステートメントで解決しました。

SELECT DISTINCT `documents`.*
FROM (`documents`)
LEFT OUTER JOIN `documents` children_documents
  ON `documents`.`id` = `children_documents`.`parent_id`
GROUP BY `documents`.`id`
HAVING SUM(CASE `children_documents`.`status` WHEN 'accepted' THEN 1 ELSE 0 END) = 0

これにより、子があるかどうかに関係なくすべてのドキュメントが選択され、受け入れられた子の数がカウントされます。行を選択するには、その数をゼロにする必要があります。

編集:好奇心のために、DataMapper ORM (CodeIgniter) でクエリをエミュレートすることができました:

$d->distinct()->where('status', 'accepted')->group_by('id')
  ->having_func('!SUM', array('[CASE]', '@children/status', '[WHEN]', 'accepted', '[THEN]', 1, '[ELSE]', 0, '[END]'), NULL);
于 2012-08-22T23:00:25.230 に答える
2
SELECT DISTINCT `documents`.*
FROM (`documents`)
LEFT OUTER JOIN `documents` children_documents
  ON `documents`.`id` = `children_documents`.`parent_id`
  AND `children_documents`.`status` = 'accepted'
WHERE `children_documents`.`parent_id` IS NULL
于 2012-08-23T02:59:56.667 に答える
1

MySQL での最速の方法は、おそらく次のようなものです。

select d.*
from documents d
where not exists (select 1
                  from documents c
                  where c.parent_id = d.id and
                        coalesce(c.status, '') = 'Accepted'
                  limit 1
                 )

これは、相関サブクエリを使用して、条件を満たさない子ドキュメントを識別します。

于 2012-08-23T01:45:00.903 に答える