0

次のテーブルがあります:tPlans、tPlansProperties、tProperties、tEventsProperties、tEvents。

これらのテーブルの場合、tPlansとtPropertiesの間には多対多の関係があります。tEventsとtPropertiesの間にも多対多の関係があります。

tPlansとすべて同じtPropertiesを持つすべてのtEventsを取得しようとしていますが、PlansとEventsの両方にプロパティが1つでもあると、結果としてそれが表示されるというジレンマに直面しています。さまざまなタイプのプロパティをすべてハードコーディングしたり、クエリされた結果を後処理したりせずに、これを実現する必要があります。

これが私がこれまでに持っているものです:

SELECT 
    P1.id
    ,P1.name
    ,E1.property
    ,E1.id 
    ,E1.name
FROM (
    SELECT 
        P.id
        , P.name
        , PP.property
    FROM tPlans P
    INNER JOIN tPlansProperties PP
    ON P.id = PP.id
) P1

INNER JOIN (
    SELECT 
        E.id
        , E.name
        , EP.property
    FROM tEvents E
    INNER JOIN tEventsProperties EP
    ON E.id = EP.id
    WHERE E.id LIKE 'EVT2011SC99'
) E1
ON P1.property = E1.property

これがテーブルの概要です。

tPlans

id、name、type、cost、vendor_id

tPlansProperties

id、property

tProperties

プロパティ、property_name、property_type

tEventsProperties

id、property

tEvents

id、name、description、date、owner_id

4

2 に答える 2

1

以下は、PlanProperties のすべてのプロパティを持つすべてのイベントを取得します。これは、あなたが求めているようです (「tPlan と同じ tProperties を持つすべての tEvent を取得しようとしています」)。

select ep.Id
from tEventsProperties ep full outer join
     (select distinct pp.property
      from PlansProperties
      -- where planid = ??
     ) pr
     on ep.property = pp.property
group by ep.Id
having count(*) = count(e.property) and
       count(*) = count(pr.property)

特定のプランで必要な場合whereは、サブクエリで句を使用します。さらにイベント情報が必要な場合は、イベント テーブルに参加してください。

これはテストされていません。

特定のイベントのプロパティに一致するすべてのプランを取得するには、次のようなクエリを実行します。

select pr.planid
from (select distinct property
      from tEventsProperties ep
      where ep.event = THEEVENT
     ) ep full outer join
     (select distinct planid, pp.property
      from PlansProperties
     ) pr
     on ep.property = pp.property
group by pr.planid
having count(*) = count(ep.property) and
       count(*) = count(pr.property)
于 2013-01-14T20:36:46.607 に答える
1

ゴードンは近かった。イベントと計画の一致するペアをすべて取得するには、もう少し複雑な結合セットが必要です。これは、非常に小さなデータ サンプルで問題なく機能するように思われるソリューションです。あなたの環境でどのように機能するかわかりません:

SELECT
  ISNULL(pp.id, pl.id) AS [plan],
  ISNULL(ev.id, ep.id) AS event
FROM
  tPlansProperties pp CROSS JOIN tEvents ev
FULL JOIN
  tEventsProperties ep CROSS JOIN tPlans pl
ON pp.property = ep.property
  AND pp.id = pl.id
  AND ev.id = ep.id
GROUP BY
  ISNULL(pp.id, pl.id),
  ISNULL(ev.id, ep.id)
HAVING COUNT(*) = COUNT(ep.property)
   AND COUNT(*) = COUNT(pp.property)
;

SQL Fiddleでも入手できます。

于 2013-01-14T21:39:29.270 に答える