加入两个表,其中第一个表的所有子记录都匹配第二个表的所有子记录

时间:2009-12-30 22:33:51

标签: sql tsql many-to-many

我有四个表:Customer,CustomerCategory,Limit和LimitCategory。客户可以是多个类别,限制也可以有多个类别。我需要编写一个查询,它将返回客户名称和限制金额,其中所有客户类别都匹配所有限制类别。

我猜它会与答案here类似,但我似乎无法做到正确。谢谢!

编辑 - 这是表格的样子:

tblCustomer
  customerId
  name

tblCustomerCategory
  customerId
  categoryId

tblLimit
  limitId
  limit

tblLimitCategory
  limitId
  categoryId

3 个答案:

答案 0 :(得分:0)

认为你正在寻找:

SELECT * 
FROM CustomerCategory 
LEFT OUTER JOIN Customer
    ON CustomerCategory.CustomerId = Customer.Id
INNER JOIN LimitCategory
    ON CustomerCategory.CategoryId = LimitCategory.CategoryId
LEFT OUTER JOIN Limit
    ON Limit.Id = LimitCategory.LimitId

答案 1 :(得分:0)

已更新!

感谢Felix指出我现有解决方案的一个缺陷(我最初发布它后3年,呵呵)。再看一遍之后,我认为这可能是正确的。在这里,我得到(1)匹配类别的客户和限制,加上匹配类别的数量,(2)每个客户的类别数量,(3)每个限制的类别数量,(4)然后我确保客户和限额的类别数量与客户和限额之间的匹配数量相同:

UNTESTED!

select
  matches.name,
  matches.limit

from (
    select
      c.name,
      c.customerId,
      l.limit,
      l.limitId,
      count(*) over(partition by cc.customerId, lc.limitId) as matchCount
    from tblCustomer c
    join tblCustomerCategory cc on c.customerId = cc.customerId
    join tblLimitCategory lc on cc.categoryId = lc.categoryId
    join tblLimit l on lc.limitId = l.limitId
) as matches

join (
    select
       cc.customerId,
       count(*) as categoryCount
     from tblCustomerCategory cc
     group by cc.customerId
) as customerCategories
on matches.customerId = customerCategories.customerId

join (
    select
      lc.limitId,
      count(*) as categoryCount
    from tblLimitCategory lc
    group by lc.limitId
) as limitCategories
on matches.limitId = limitCategories.limitId

where matches.matchCount = customerCategories.categoryCount
and matches.matchCount = limitCategories.categoryCount

答案 2 :(得分:-1)

我不知道这是否会起作用,只是一个想法,我无法测试它,我确实有一个更好的方式!不要太苛刻:)

  SELECT 
   c.customerId
 , l.limitId
FROM 
 tblCustomer c
CROSS JOIN 
 tblLimit l
WHERE NOT EXISTS
(
 SELECT 
  lc.limitId 
 FROM 
  tblLimitCategory lc 
 WHERE 
  lc.limitId = l.id
 EXCEPT
 SELECT
  cc.categoryId 
 FROM 
  tblCustomerCategory cc 
 WHERE 
  cc.customerId = l.id
)