4

親テーブルがある場合

create table parent (
  pid int not null,
  name varchar(255)
)

および親子結合テーブル

create table parent_child (
  pid int not null,
  cid int not null,
  foreign key (pid) references parent(pid),
  foreign key (cid) references child(cid)
)
create table child(
  cid int not null,
  name varchar(255)
)

すべての子供の名前が次のリスト ('dave'、'henry'、'myriam'、'jill') にあるすべての親の名前を見つけるにはどうすればよいですか。

別の名前の子供がいる場合は親に会いたくありませんが、1人以上の子供がいて、すべての子供の名前がリストにある場合は、親の名前を見たいです。

私はこれを見つけましたhttps://stackoverflow.com/a/304314/1916621正確にそれらの名前の子供を持つ親を見つけるのに役立ちますが、名前を持つ子供しか持たない親への方法がわかりませんそのリストのサブセット。

誰かがさまざまなアプローチのパフォーマンスのトレードオフを知っている場合は、追加のポイント。

4

2 に答える 2

3
SELECT 
    p.pid, 
    p.name
FROM 
    parent p
WHERE NOT EXISTS (
    SELECT *
    FROM 
        parent_child pc 
        JOIN child c 
            ON pc.cid = c.cid
            AND c.name NOT IN ('dave','henry','myriam','jill')
    WHERE 
        p.pid = pc.pid
) AND EXISTS (
    SELECT *
    FROM 
        parent_child pc 
        JOIN child c 
            ON pc.cid = c.cid
            AND c.name IN ('dave','henry','myriam','jill')
    WHERE 
        p.pid = pc.pid
)

別の方法...サブクエリはありませんが、テーブルへの結合によるレコードDISTINCTの重複を排除するために追加が必要です。parentparent_child

SELECT DISTINCT
    p.pid, 
    p.name
FROM 
    parent p 
    JOIN parent_child pc_exists ON pc_exists.pid = p.pid
    JOIN child c_exists 
        ON c_exists.cid = pc_exists.cid
        AND c_exists.name IN ('dave','henry','myriam','jill')
    LEFT JOIN parent_child pc_notExists ON pc_notExists.pid = p.pid
    LEFT JOIN child c_notExists 
        ON c_notExists.cid = pc_notExists.cid
        AND c_notExists.name NOT IN ('dave','henry','myriam','jill')
WHERE
    c_notExists.cid IS NULL
于 2012-12-19T21:38:46.430 に答える
1

これが私の適度な賭けです:

サンプルテーブル:

PID     NAME
1       dad john
2       mum sandy
3       dad frank
4       mum kate
5       mum jean

CID     NAME
11      dave
22      maryam
33      henry
44      maryam
16      jill
17      lina
23      jack
34      jill
55      dave

Parent_Child

PID     CID
1       11
1       16
1       17
2       22
3       33
4       44
2       23
5       55
3       34

クエリ:

select p.pid, p.name, 
group_concat(c.name) as children
from parent as p
inner join parent_child as pc
on p.pid = pc.pid
join child as c
on pc.cid = c.cid
where c.name
in ('dave','henry','maryam','jill')
group by p.pid
;

結果:

PID     NAME        CHILDREN
1       dad john    dave,jill
2       mum sandy   maryam
3       dad frank   henry,jill
4       mum kate    maryam
5       mum jean    dave

REGEXPとGROUP_CONCATの使用

これは、SQLよりinもはるかに優れています。find_in_set私が行った変更、私はリストをcomma delimitted string;)として使用しました

*しかし、ここでの問題:そのgroup_concat文字列の順序は、コンマで配信される文字列で見つける必要があります。*REGEXP非常に効率的にしない限り:)

クエリ:

select x.pid, x.name,
x.children from(
select p.pid, p.name, 
group_concat(c.name) as children,
  count(c.name) as counts
from parent as p
inner join parent_child as pc
on p.pid = pc.pid
join child as c
on pc.cid = c.cid
group by p.pid) as x
where 'dave,maryam,henry,jill'
REGEXP x.children
;

結果:

PID     NAME        CHILDREN
3       dad frank   henry,jill
4       mum kate    maryam
5       mum jean    dave

* SQLFIDDLE

于 2012-12-19T21:58:52.843 に答える