Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Oracle在两个不同的列中查找公共值_Sql_Oracle - Fatal编程技术网

Sql Oracle在两个不同的列中查找公共值

Sql Oracle在两个不同的列中查找公共值,sql,oracle,Sql,Oracle,如果我有这样一个结构: CREATE TABLE things ( id, personA varchar2, personB varchar2, attribute ..., ) 我想找到,对于一个给定的属性,如果我的所有东西至少有一个普通人,我该怎么做 因此,如果我的数据是(每个属性可能超过2个): 对于苹果,史蒂夫是我的普通人,对于橘子,保罗和拉里都是,对于西红柿,我没有普通人。但是,我不需要一个同时返回所有这些内容的查询。我有其中一个属性,需要0、1或2

如果我有这样一个结构:

CREATE TABLE things (
    id,
    personA varchar2,
    personB varchar2,
    attribute ...,
)
我想找到,对于一个给定的属性,如果我的所有东西至少有一个普通人,我该怎么做

因此,如果我的数据是(每个属性可能超过2个):


对于苹果,史蒂夫是我的普通人,对于橘子,保罗和拉里都是,对于西红柿,我没有普通人。但是,我不需要一个同时返回所有这些内容的查询。我有其中一个属性,需要0、1或2行,具体取决于我的公共性。我一直在想办法,但还不太清楚。

这将为您提供
普通人
/
属性
列表。我根据你的样本数据运行了它,得到了预期的结果。希望它至少指向了正确的方向:)


如果您使用的是11gR2,您还可以使用来避免自连接:

select person, attribute
from (
    select *
    from things
    unpivot (person for which_person in (persona as 'A', personb as 'B'))
)
group by person, attribute
having count(*) > 1;

PERSON     ATTRIBUTE
---------- ----------
Steve      Apple
Paul       Orange
Larry      Orange

3 rows selected.
或者只针对符合该属性的人,我认为这就是你问题的目的:

select person
from (
    select *
    from things
    unpivot (person for which_person in (persona as 'A', personb as 'B'))
)
where attribute = 'Apple'
group by person, attribute
having count(*) > 1;

PERSON
----------
Steve

1 row selected.

unpivot
将列转换为行。独立运行它将原来的六行转换为十二行,将原来的
persona
/
personb
列替换为一个
person
和一个额外的列,该列指示新行是从哪个列组成的,我们在这里并不关心:

select *
from things
unpivot (person for which_person in (persona as 'A', personb as 'B'));

        ID ATTRIBUTE  W PERSON
---------- ---------- - ----------
         1 Apple      A John
         1 Apple      B Steve
         2 Apple      A Steve
         2 Apple      B Larry
         3 Orange     A Paul
         3 Orange     B Larry
         4 Orange     A Paul
         4 Orange     B Larry
         5 Tomato     A Chris
         5 Tomato     B Michael
         6 Tomato     A Steve
         6 Tomato     B Larry

12 rows selected.
然后外部查询执行一个简单的分组。

这里有一个方法

它通过交叉连接到一个数字列表(您可以使用Alex使用的unpivot方法)来实现unpivot方法,然后连接结果集,希望通过哈希连接来增加优点

with
  row_generator as (
    select 1 counter from dual union all
    select 2 counter from dual),
  data_generator as (
    select
      attribute,
      id       ,
      case counter
        when 1 then persona
        when 2 then personb
      end person
    from
      things,
      row_generator)
select
  t1.attribute,
  t1.person
from
  row_generator t1,
  row_generator t2
where
  t1.attribute = t2.attribute and
  t1.person    =  t2.person   and
  t1.id        != t2.id;

您需要一个
自联接
。如果不希望在一个查询中包含所有匹配项,则可以将特定属性指定为
ON
表达式中的
的一部分,或者在之后使用WHEN将其过滤掉。
select *
from things
unpivot (person for which_person in (persona as 'A', personb as 'B'));

        ID ATTRIBUTE  W PERSON
---------- ---------- - ----------
         1 Apple      A John
         1 Apple      B Steve
         2 Apple      A Steve
         2 Apple      B Larry
         3 Orange     A Paul
         3 Orange     B Larry
         4 Orange     A Paul
         4 Orange     B Larry
         5 Tomato     A Chris
         5 Tomato     B Michael
         6 Tomato     A Steve
         6 Tomato     B Larry

12 rows selected.
with
  row_generator as (
    select 1 counter from dual union all
    select 2 counter from dual),
  data_generator as (
    select
      attribute,
      id       ,
      case counter
        when 1 then persona
        when 2 then personb
      end person
    from
      things,
      row_generator)
select
  t1.attribute,
  t1.person
from
  row_generator t1,
  row_generator t2
where
  t1.attribute = t2.attribute and
  t1.person    =  t2.person   and
  t1.id        != t2.id;