0

我有以下表格:tPlans、tPlansProperties、tProperties、tEventsProperties、tEvents。

对于这些表,tPlans 和 tProperties 之间存在多对多关系。tEvents 和 tProperties 之间也存在多对多关系。

我正在尝试获取与 tPlans 具有所有相同 tProperties 的所有 tEvents,但我遇到了两难境地,如果计划和事件中甚至有一个属性,它会显示它作为结果。我需要在不对所有不同类型的属性进行硬编码或对查询结果进行后处理的情况下实现这一点。

这是我到目前为止所拥有的:

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

这是表格的高级视图:

计划

ID,名称,类型,成本,vendor_id

tPlansProperties

身份证,财产

t属性

属性,property_name,property_type

tEventsProperties

身份证,财产

事件

id、名称、描述、日期、owner_id

4

2 回答 2

1

以下获取具有 PlanProperties 中所有属性的所有事件,这似乎是您所要求的(“我正在尝试获取与 tPlans 具有所有相同 tProperties 的所有 tEvents”):

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 回答