SQL查询逻辑建议

时间:2014-05-18 05:08:15

标签: sql oracle

我出于特殊情况,需要获得编写SQl查询的逻辑,尝试我的水平最好但仍然受到打击。

我有公司名单以及相应的董事。让我们假设公司' x'有5位董事(aa,bb,cc,dd,ee)。需要查明列表中的任何其他公司是否具有相同的董事(即)(aa,bb,cc,dd,ee也存在于公司' z'中)。即使一位导演有所不同,也没有必要考虑它。

让我们考虑简单的例子

company   director
-------------------
a         xx
a         yy
b         zz
b         xx
c         xx
c         yy

需要O / P(因为a和c具有相同的导演集)

company1  company2  director
---------------------------
a         c         xx
a         c         yy
到目前为止逻辑尝试了: 用于比较的复制输入表,执行简单的内连接,获取值,在分组公司名称中存在真正的问题,这在每次迭代中都很麻烦。

任何人都可以提供同样的帮助。真的很感激

4 个答案:

答案 0 :(得分:0)

我可以想到使用listagg

的黑客攻击
 with x as (
    select 'A' as company, 1 as director from dual union all
    select 'A' as company, 2 as director from dual union all
    select 'B' as company, 1 as director from dual union all
    select 'B' as company, 3 as director from dual union all
    select 'B' as company, 4 as director from dual union all
    select 'C' as company, 1 as director from dual union all
    select 'C' as company, 2 as director from dual union all
    select 'D' as company, 4 as director from dual union all
    select 'E' as company, 4 as director from dual union all
    select 'F' as company, 5 as director from dual union all
    select 'F' as company, 4 as director from dual union all
    select 'G' as company, 4 as director from dual union all
    select 'G' as company, 5 as director from dual
 ) , companies as (
 select     company,
    listagg(director,',') within group (order by director) directors
 from       x
 group by company
 )
 select     directors,
    listagg(company,',') within group (order by company) as companies
 from       companies
 group by directors
 having count(*) > 1

,结果是

DIRECTORS                      COMPANIES
------------------------------ ------------------------------
1,2                            A,C
4                              D,E
4,5                            F,G

PS:如果您需要获取数据以进行进一步操作并且字符串类型不可用,则可以使用COLLECT代替LISTAGG,但您必须定义具有TYPEMAP功能的自定义ORDER,可以按收集的值列表进行分组。

答案 1 :(得分:0)

我的SQL有点生疏,但我尝试这样的事情:

SELECT c1, c2 FROM
(select company as c0, count(director) as cd0 from data group by company) ALPHA
JOIN
(select count(d.director) as d0, d.company as c1, d.director as d1, e.company as c2, e.director as d2 from data d LEFT JOIN data e ON d.director = e.director
WHERE d.company <> e.company
group by c1, c2) BETA
ON ALPHA.cd0 = BETA.d0 AND ALPHA.c0 = BETA.c1

如果你SELECT *以上,则会看到d1列或d2列为您xxxx yy和{{1}} 1}}在结果集中。但是,它应该足够简单,可以编写一个外部查询来为您提供。

说明:我计算公司董事与其他公司董事的联合,并检查公司董事的董事人数。在您的示例中:

公司a有2名董事,两人都只与公司c匹配 b公司有2名董事,对公司a和c没有匹配 公司c有2名董事,两人都与公司a。

匹配

这使a和c完美匹配。

我测试了一些更多的虚拟数据,以及有3或4个目录的公司,并且它也适用于那些。

答案 2 :(得分:0)

这个怎么样:

WITH dirlist AS (
  SELECT company, LISTAGG(director, ',') WITHIN GROUP (ORDER BY director) directors
  FROM companies
)
SELECT DISTINCT c1.company, c2.company, c1.directors
FROM dirlist c1, dirlist c2
WHERE c1.directors=c2.directors;

编辑:我现在可以看到我没有完全回答你的问题。此查询仅检测匹配(不消除重复和selfjoins)。希望它有所帮助。

答案 3 :(得分:0)

GoranM对答案的略微更新

WITH dirlist AS (
  SELECT company, LISTAGG(director, ',') WITHIN GROUP (ORDER BY director) directors
  FROM companies
)

SELECT c1.company, MAX(c2.company), COUNT(c1.directors) AS DuplicateDirList
FROM dirlist c1, dirlist c2
WHERE c1.directors=c2.directors;
GROUP BY c1.company
HAVING COUNT(c1.directors) >1

这将为您提供一家公司,其中包含一名双重董事和第一家重复的公司。