【问题标题】:SQL - How to solve this query?SQL - 如何解决这个查询?
【发布时间】:2017-04-30 02:30:54
【问题描述】:

我想弄清楚如何解决这个问题。

选择曾为 IBM 和 Microsoft 工作过的候选人。

与数据库关联的表包括

Candidate(Id,Name)
Company(Id,Name)
hasWorkedFor(CandidateId,CompanyId)

其中 CandidateId 和 Company Id 是 Candidate 表和 Company 表的外键。

我得到的查询是:

SELECT Candidate.Name 
FROM Candidate x, Candidate y, Company c1, Company c2, hasWorkedFor 
WHERE x.Id = Id 
  AND c1.Id = CompanyId
  AND c1.Name = "Microsoft" 
  AND c2.Id = CompanyId  
  AND c2.Name = "IBM";

任何帮助将不胜感激。

【问题讨论】:

  • 我删除了不兼容的数据库标签。请仅使用您真正使用的数据库进行标记。而且——关于正确行事的话题——从不FROM子句中使用逗号。
  • Bad habits to kick : using old-style JOINs - 旧式 逗号分隔的表格列表 样式已替换为 ANSI 中的 proper ANSI JOIN 语法-92 SQL 标准(25 年前),不鼓励使用它

标签: sql subquery


【解决方案1】:

试试这个:

select Candidate.* from Candidate inner join (
    select CandidateId from hasWorkedFor inner join Company
    on hasWorkedFor.CompanyId = Company.id
    where Company.name in ('IBM', 'Microsoft')
    group by CandidateId
    having count(distinct CompanyId) = 2
)t
on Candidate.Id = t.CandidateId

请注意,此查询还提供了那些可能为其他公司工作的候选人

如果您需要为 IBM 和 Microsoft 工作的候选人,那么您可以使用:

select Candidate.* from Candidate inner join (
    select t1.CandidateId from (
        select CandidateId   from hasWorkedFor inner join Company
        on hasWorkedFor.CompanyId = Company.id
        where Company.name in ('IBM', 'Microsoft')
        group by CandidateId
        having count(distinct CompanyId) = 2
    )t1 inner join(
        select CandidateId from hasWorkedFor 
        inner join Company
        on hasWorkedFor.CompanyId = Company.id
        group by CandidateId
        having count( distinct CompanyId ) = 2
    ) t2 on t1.CandidateId = t2.CandidateId
)t
on Candidate.Id = t.CandidateId

【讨论】:

    【解决方案2】:

    试试这个代码:

    select candidate.name from candidate 
    inner join hasworkedfor 
    on candidate.id = hasworkedfor .candidateid inner join company 
    on hasworkedfor .companyid = company.id 
    where company.name = 'Microsoft' and company.name  = 'IBM'
    

    【讨论】:

      【解决方案3】:
      SELECT ca.Name FROM Candidate ca 
          WHERE ca.Id IN (SELECT hw.CandidateId FROM hasWorkedFor hw 
                              LEFT OUTER JOIN Company co ON hw.CompanyId = co.Id WHERE co.Name = 'Microsoft') AND
                ca.Id IN (SELECT hw.CandidateId FROM hasWorkedFor hw 
                              LEFT OUTER JOIN Company co ON hw.CompanyId = co.Id WHERE co.Name = 'IBM')
      

      SELECT ca.Name FROM Candidate ca 
          WHERE COUNT(SELECT DISTINCT hw.CompanyId FROM hasWorkedFor hw 
                              LEFT OUTER JOIN Company co ON hw.CompanyId = co.Id 
                              WHERE (co.Name = 'Microsoft' OR co.Name = 'IBM') AND hw.CandidateId = ca.Id) = 2
      

      【讨论】:

        【解决方案4】:
        select * from Candidate c where
        exists(select * from hasWorkedFor w where w.CandidateId=c.Id and w.CompanyId = 'Microsoft')
        and exists(select * from hasWorkedFor w where w.CandidateId=c.Id and w.CompanyId = 'IBM')
        

        也就是说,从Candidate where中选择

        • 存在他在 MSFT 工作的条目,并且
        • 存在他在 IBM 工作的条目

        【讨论】:

          【解决方案5】:

          我的解决方案:

          SELECT ca.Name
          FROM Company cm
          JOIN hasWorkedFor wk ON cm.Id = wk.CompanyId
          JOIN Candidate ca ON wk.CandidateId = ca.Id
          WHERE cm.Name IN ('IBM', 'Microsoft')
          GROUP BY ca.Id,ca.Name
          HAVING COUNT(*) = 2
          

          【讨论】:

            【解决方案6】:

            试试这个,如果有任何疑问,请告诉我。

            select a.name as candiate_name
            from
               candidate a
            left join
               hasworkedfor b
            on a.id = b.candidateid
            left join
               company c
            on b.companyid = c.id
            where c.name = 'Microsoft' and c.name  = 'IBM';
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-09-03
              • 2021-05-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-01-03
              相关资源
              最近更新 更多