代码之家  ›  专栏  ›  技术社区  ›  adam0101

联接两个表,其中第一个表的所有子记录与第二个表的所有子记录都匹配

  •  0
  • adam0101  · 技术社区  · 15 年前

    我有四个表:客户、客户类别、限制和限制类别。客户可以有多个类别,限额也可以有多个类别。我需要编写一个查询,返回所有客户类别与所有限制类别匹配的客户名称和限制金额。

    我猜这和答案差不多 here 但我似乎不能把它弄好。谢谢!

    编辑 -这是桌子的样子:

    tblCustomer
      customerId
      name
    
    tblCustomerCategory
      customerId
      categoryId
    
    tblLimit
      limitId
      limit
    
    tblLimitCategory
      limitId
      categoryId
    
    3 回复  |  直到 12 年前
        1
  •  0
  •   Nathan Wheeler    15 年前

    思考 你在找:

    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
    
        2
  •  0
  •   adam0101    12 年前

    更新!

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

    未经考验!

    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
    
        3
  •  -1
  •   Paul Creasey    15 年前

    我不知道这是否有效,只是我的一个想法,我不能测试它,我确信有一个更好的方法!不要太苛刻。)

      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
    )