oracle 仅从两个表中选择匹配的记录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7115570/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 00:15:35  来源:igfitidea点击:

select only matching records from two tables

sqloracle

提问by niceApp

I am using Oracle 10g Here is my scenario:

我正在使用 Oracle 10g 这是我的场景:

I have two tables

我有两张桌子

class1(groupName, subgroup)
class2(groupName, subgroup, ind)

Here is my data looks like:

这是我的数据看起来像:

class1
groupName  subgroup
     A      1
     A      2
     B      3
     C      4
     C      4
     C      5
     D      6


class2
groupName  subgroup IND
     A      1        Y     
     A      1        N
     A      2        Y
     A      2        N
     B      3        Y
     C      4        Y
     C      4        N

Now, I need to get the data that has the matching groupName and subGroup in both class1 and class2(Not necessarily distinct match). In addition to that the IND column should have pair of 'Y' and 'N' value for each subgroup in class 2. Eg.In the above example GroupName A is qualified because A exists in both class1 and class2 and it has subgroup 1 and 2 exist in both class1 and class2 and IND column in class2 table has a pair of 'Y' and 'N' for each subgroup (i.e 1 and 2).

现在,我需要获取在 class1 和 class2 中具有匹配 groupName 和 subGroup 的数据(不一定是不同的匹配)。除此之外,IND 列应该为类 2 中的每个子组提供一对“Y”和“N”值。例如,在上面的示例中,GroupName A 是合格的,因为 A 存在于类 1 和类 2 中,并且它具有子组 1 和2 存在于 class1 和 class2 中,并且 class2 表中的 IND 列对于每个子组(即 1 和 2)都有一对“Y”和“N”。

Rest of the records are not qualified because : Group B has subgroup 3 that exists in both class1 and class2 but it does not have 'Y' and 'N' pairs for subgroup 3 in class2. Group C and D are not qualified because its all subgroup (4,5) doesn't exist in class2.

其余记录不合格,因为:B 组具有同时存在于 class1 和 class2 中的子组 3,但它在 class2 中没有子组 3 的“Y”和“N”对。组 C 和 D 不合格,因为它的所有子组 (4,5) 在 class2 中都不存在。

I have more than 700,000 records on both table class1 and class2. Anyone has any idea what is the effective way to get this information.

我在表 class1 和 class2 上都有超过 700,000 条记录。任何人都知道获取这些信息的有效方法是什么。

回答by bobs

Does this create what you need?

这是否创造了您需要的东西?

SELECT *
FROM class1 c1
JOIN class2 c2 ON c1.groupName = c2.groupName
        AND c1.subgroup = c2.subgroup
WHERE
    (
    SELECT COUNT(DISTINCT ind)
    FROM class2 c2a
    WHERE c2a.groupName = c1.groupName
        AND c2a.subgroup = c2a.subgroup
    ) = 2
  AND
    (
    SELECT COUNT(DISTINCT subgroup)
    FROM class1 c1b
    WHERE c1b.groupName = c1.groupName
    ) =
    (
    SELECT COUNT(DISTINCT subgroup)
    FROM class2 c2b
    WHERE c2b.groupName = c2.groupName
    )

回答by ThinkJet

Something like that must help ...

这样的事情必须帮助...

select 
  groupName
from (

  select -- Get number of good subgroups for each group
    groupName                      as groupName,
    subGroupCount                  as subGroupCount,
    sum( decode(ynCount, 2,1, 0) ) as goodGroupCount
  from (

      select -- Find which subgroups are good (contains both Y and N)
        c1set.groupName        as groupName,
        c1set.subGroup         as subGroup,
        c1set.subGroupCount    as subGroupCount,
        count(distinct c2.IND) as ynCount
      from
        (
          select -- Collect group/subgroup sets and get number of subGroups
            distinct 
              c1.groupName                        as groupName,
              c1.subGroup                         as subGroup,
              count(distinct c1.subGroup)
                over (parttition by c1.groupName) as subGroupCount
          from
            class1 c1
        )
               c1set,
        class2 c2
      where
        c2.groupName (+) = c1set.groupName
        and
        c2.subGroup (+) = c1set.subGroup
      group by
        c1set.groupName,
        c1set.subGroup,
        c1set.subGroupCount

    )
  group by
    groupName, subGroupCount

)
where
  subGroupCount = goodGroupCount

Sorry, I can't test this code now by myself. Please comment if you found any inconsistency.

抱歉,我现在无法自己测试此代码。如果您发现任何不一致之处,请发表评论。

回答by Mikeb

If it doesn't matter that the IND column has Y and N specifically, you could do this:

如果 IND 列有 Y 和 N 无关紧要,您可以这样做:

select t1.groupName from
( select count(class1.groupName) a, groupName from class1 group By groupName) t1
 inner join 
( select count(class2.groupName) a, groupName from class2 group by groupName) t2
on t1.groupName = t2.groupName and 2*t1.a = t2.a

If it does matter, you could probably modify the second inner query like so:

如果确实重要,您可能可以像这样修改第二个内部查询:

select count(class2.groupName) a, groupName from class2 group by groupName
  having  max(ind) = 'Y' and min(ind) = 'N'

Edit to support additional tests mentioned in comments:

编辑以支持评论中提到的其他测试:

select distinct t1.groupName from
( select count(class1.groupName) a, groupName, subgroup from class1 
  group By groupName, subgroup) t1
 inner join 
( select count(class2.groupName) a, groupName, subgroup from class2 
  group by groupName, subgroup
  having  max(ind) = 'Y' and min(ind) = 'N') t2
on t1.groupName = t2.groupName and t1.subgroup = t2.subgroup and 2*t1.a = t2.a