开发者

Join two tables where all child records of first table match all child records of second table

开发者 https://www.devze.com 2022-12-15 07:11 出处:网络
I have four tables: Customer, CustomerCategory, Limit, and LimitCategory. A customer can be inmultiple categories and a limit can also have multiple categories. I need to write a query that will retur

I have four tables: Customer, CustomerCategory, Limit, and LimitCategory. A customer can be in multiple categories and a limit can also have multiple categories. I need to write a query that will return the customer name and limit amount where ALL the customers categories match ALL the limit categories.

I'm guessing it would be similar to the answer here, but I can't seem to get it ri开发者_运维百科ght. Thanks!

Edit - Here's what the tables look like:

tblCustomer
  customerId
  name

tblCustomerCategory
  customerId
  categoryId

tblLimit
  limitId
  limit

tblLimitCategory
  limitId
  categoryId


I THINK you're looking for:

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


Updated!

Thanks to Felix for pointing out a flaw in my existing solution (3 years after I originally posted it, hehe). After looking at it again, I think this might be correct. Here I'm getting (1) the customers and limits with matching categories, plus the number of matching categories, (2) the number of categories per customer, (3) the number of categories per limit, (4) I then ensure the number of categories for customer and limits is the same as the number of the matches between the customers and limits:

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


I don't know if this will work or not, just a thought i had and i can't test it, I'm sures theres a nicer way! don't be too harsh :)

  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
)
0

精彩评论

暂无评论...
验证码 换一张
取 消