0

我有一个表 P,其中包含 personid 列和 licensetypeid 列。

每个人都可以拥有多种许可证类型,为该人 ID 向表中添加额外的行。

我需要找到 personid 的 licenseid 为 1 和 5 的行。

我不能写:

SELECT personid, licensetypeid 
FROM P 
WHERE licensetypeid=1 AND licensetypeid=5;

我听说我应该使用自加入来执行此操作。如何进行自我加入以解决此问题?

4

5 回答 5

4

自联接和其他多次访问表的技术将起作用,但如果您需要泛化到更大的 id 集,可能会降低性能并且不实用。

您可以通过计算每个人的匹配行数来对表进行一次引用:

select personid from P
  where licensetypeid in ('1','5')
  group by personid
  having count(*) = 2

如果您需要更大的 licensetypeid 值,这可以很容易地扩展:

select personid from P
  where licensetypeid in ('1','5','7')
  group by personid
  having count(*) = 3

(在自联接版本中,您必须为每个附加值添加一个附加联接)

或者,如果您想在更大的一组类型中找到至少具有 2 种类型的人:

select personid from P
  where licensetypeid in ('1','5', '7', '10')
  group by personid
  having count(*) >= 2

现在,与您的示例查询不同,licensetypeid 不包含在结果集中。如果出于某种原因有必要这样做,您可以在 2 个值的情况下做一个简单的技巧:

select personid, min(licensetypeid) licensetype1, max(licensetypeid) licensetype2
  from P
  where licensetypeid in ('1','5')
  group by personid
  having count(*) = 2

但更通用的方法是将值分组到一个简单的集合中:

select personid, collect(licensetypeid) licensetypeidlist
  from P
  where licensetypeid in ('1','5')
  group by personid
  having count(*) = 2
于 2011-04-07T14:53:57.693 回答
2
select personid, licensetypeid
from P P1
where exists (
   select 1
   from P P2
   where P2.personid = P1.personid
      and P2.licensetypeid = 1
) and exists (
   select 1
   from P P2
   where P2.personid = P1.personid
      and P2.licensetypeid = 5
)
于 2011-04-07T11:53:21.080 回答
1
SELECT distinct
       p1.personid
      ,p1.licensetypeid 
      ,p2.licensetypeid
from P p1, P p2
WHERE p1.personid = p2.personid
AND   p1.licensetypeid = 1
AND   p2.licensetypeid = 5
;
于 2011-04-07T12:02:36.240 回答
0

尝试这个

select personid,licensetypeid from P where licensetypeid in ('1','5')
于 2011-04-07T11:30:58.377 回答
0

如果您的所需许可证类型集是“固定的”,或者至少如果所需许可证类型集的基数是固定的,那么给定的答案将可以正常工作。

否则,您需要编写与所谓的“关系除法”等效的 SQL。

情况如下:

(1) 计算至少缺少一种所需许可证类型的人员集:

SELECT personid 
from P 
WHERE EXISTS
  (
    SELECT licenseid 
    from NEEDEDLICENSETYPE AS NLT 
    WHERE NOT EXISTS (
      SELECT * 
      FROM P AS PBIS 
      WHERE 
        PBIS.personid = P.personid AND
        PBIS.licensetype = NLT.licensetype
    )
  )

NEEDELICENSETYPE 表示在特定调用中计算所需许可证类型集所需的任何 SQL 语句。

(2) 选择 (1) 中没有出现数字的人的数据:

SELECT ... FROM P WHERE personid NOT IN (...)
于 2011-04-07T12:27:19.910 回答