2010-08-06 90 views
2

我有一个SQL查询,我不能笼络我的脑海。我没有大量的sql经验。所以,我需要一些帮助简单的SQL问题

我有一个表XXX:

Social Security No (SSN). 
Name. 
organisation. (Finance/IT) 

英语我要的是:

要选择在“财经”那里是一个不同名称的所有攻击潜艇和名称对于“IT”中的SSN。

我不工作的尝试:

选择SSN,名字来自XXX其中有机= “财经” 和名称没有(来自XXX选择名称,其中有机= “IT” 和SSN = the_first_ssn)

请帮忙。


我决定让它更难一点。

SSN可以在“IT” OCUR多次:

所以我想在“IT”

回答

3

选择所有核潜艇和名称在财政当SSN不存在同名的你可以在一个exists子句中使用子查询:

select ssn, name 
from YourTable a 
where organisation = 'Finance' 
     and exists 
     (
     select * 
     from YourTable b 
     where organisation = 'IT' 
       and a.ssn = b.ssn 
       and a.name <> b.name 
     ) 

子查询说,必须有一个排它与同SSN,但不同的名称。

+0

这正是我所希望的。它看起来像我需要将表格存储为“a”,然后我可以忽略sriginal querys数据。 完美。 谢谢。 – Mark 2010-08-06 11:15:33

1

假设SSN是一个独特的关键...

select ssn, name 
from XXX XXX1 
where org = "Finance" 
and ssn in 
(
select ssn 
from XXX XXX2 
where org="IT" 
and XXX1.name<>XXX2.name 
) 
0
SELECT distinct 
t1.ssn, 
t1.name 
from 
xxx t1 
inner join xxx t2 on t1.ssn=t2.ssn and t1.name<>t2.name 
where t1.org='Finance' and t2.org='IT' 
0

我知道我迟到了,但我在努力学习SQL,我想试试我的手在解决方案并与现有答案进行比较。我用一些测试数据创建了一个表Personnel

  1. 我的SQL Server只查询使用热膨胀系数和INNER JOIN

    WITH 
        Finance AS (SELECT SSN, Name FROM Personnel WHERE Org = 'Finance'), 
        IT AS (SELECT SSN, Name FROM Personnel WHERE Org = 'IT') 
    SELECT Finance.SSN, Finance.Name 
        FROM Finance 
        INNER JOIN IT ON IT.SSN = Finance.SSN 
        WHERE IT.Name != Finance.Name 
    
  2. Alexander's solution采用的是直板INNER JOIN。我改写了那么一点点,把WHERE子句中的名称比较,并下探DISTINCT因为它不是必需的:

    SELECT Finance.SSN, Finance.Name 
        FROM Personnel Finance 
        INNER JOIN Personnel IT ON Finance.SSN = IT.SSN 
        WHERE 
         (Finance.Org = 'Finance' AND IT.Org = 'IT') AND 
         (Finance.Name != IT.Name) 
    
  3. Andomar's solution使用相关子查询的EXISTS子句中:

    SELECT SSN, Name 
        FROM Personnel a 
        WHERE 
         (Org = 'Finance') AND 
         EXISTS 
         (
          SELECT * 
           FROM Personnel b 
           WHERE (Org = 'IT') AND (a.SSN = b.SSN) AND (a.Name != b.Name) 
         ) 
    
  4. barrylloyd's solution使用IN子句中的相关子查询:

    SELECT SSN, Name 
        FROM Personnel p1 
        WHERE 
         (Org = 'Finance') AND 
         SSN IN 
         (
          SELECT SSN FROM Personnel p2 
           WHERE (Org = 'IT') AND (p1.Name != p2.Name) 
         ) 
    

我将所有这些插入到SQL Server中,事实证明,查询1和2都生成相同的查询计划,并且查询3和4生成相同的查询计划。两组之间的区别在于前组实际上在内部执行INNER JOIN,而后一组执行左半连接。 (See here对于不同类型的连接的解释。)

我假设有一个轻微的性能优势有利于左半连接;但是,对于商业案例,如果要查看右表中的任何数据列(例如,如果要显示两个名称以进行比较),则必须完全重写这些查询才能使用INNER JOIN - 基于解决方案

因此,鉴于所有这一切,我会赞成解决方案2,因为性能与3和4非常相似,并且它比那些更灵活。我的解决方案使SELECT语句非常易于阅读,但它比2更冗长,并且不便携。如果您必须对两个“子表”中的每一个进行额外的筛选,或者如果此查询的结果将用作进一步目标的中间步骤,那么我认为我的可读性可能会更好。