3

我有表 A、B 和 C

B 与 A 多对一相关

我想找到所有A,其中C是B的完整子集。

以下 LINQ 查询(伪代码)代表我想要得到的。

class A
{
    public B[] Bs { get; set; }
}

class B
{
    public string Text { get; set; }
}

class C
{
    public string Text { get; set; }
}

private static IEnumerable<A> Search(C[] C, A[] A)
{
    return from a in A
            where C.All(c => a.Bs.Any(b => SomeCondition(b, c)))
            select a;
}

private static bool SomeCondition(B b, C c)
{
    //There we comparing B and C
    throw new NotImplementedException();
}

我有以下表结构

A ( a_ID INT PRIMARY KEY )
B ( b_ID INT PRIMARY KEY, a_ID INT, Text NVARCHAR(MAX) )
C ( c_ID INT PRIMARY KEY, Text NVARCHAR(MAX) )

我需要得到 ALL A,其中 B 匹配所有 C。

例子

A | a_ID |
  | 1    |
  | 2    |
  | 3    |

B | b_ID | a_ID | Text  |
  | 1    | 1    | Cat   |
  | 2    | 1    | Dog   |
  | 3    | 1    | Rabbit| 
  | 4    | 2    | Cat   | 
  | 5    | 2    | Cat   | -- B can contain duplicates
  | 6    | 2    | Rabbit|

C | c_ID | Text |
  | 1    | Cat  |
  | 2    | Dog  |

输出

| a_ID |
| 1    |
4

2 回答 2

1

UPDATED3:计算不同的 c_id

SELECT b.a_id
  FROM b
  JOIN c ON b.Text = c.Text
GROUP BY b.a_id
HAVING COUNT(distinct c.c_id) = (SELECT COUNT(*) FROM C)

输出:

| A_ID |
--------
|    1 |

这是一个sqlfiddle 示例

于 2013-03-07T03:00:25.983 回答
0

好的,我想出了如何制作它。

假设x=>x.All(e => predicate(e))可以转换为x=>!x.Any(e => !predicate(e))

我们可以将原始表达式转换为以下表达式

from a in A
where !C.Any(c => !a.Bs.Any(b => SomeCondition(b, c)))
select a;

任何都可以使用exists关键字转换为 SQL

我会假设这SomeCondition是平等的

先转换!a.Bs.Any(b => SomeCondition(b, c))成SQL

NOT EXISTS (
    SELECT 1 FROM B b
        WHERE a.a_id = b.a_id -- a will be added later
          AND c.Text = b.Text -- c will be added later
)

下一个转换!C.Any(c => !a.Bs.Any(b => SomeCondition(b, c)))

NOT EXISTS (
    SELECT 1 FROM C c
    WHERE NOT EXISTS (
        SELECT 1 FROM B b
        WHERE a.a_id = b.a_id -- a will be added later
          AND c.Text = b.Text
    )
)

最后是整个表情

SELECT * FROM A a
WHERE NOT EXISTS (
    SELECT 1 FROM C c
    WHERE NOT EXISTS (
        SELECT 1 FROM B b
        WHERE a.a_id = b.a_id
          AND c.Text = b.Text
    )
)

现在我们可以做一些优化

于 2013-03-07T21:33:22.613 回答