简单的SQL问题

时间:2010-08-06 10:46:35

标签: sql tsql

我有一个SQL查询,我无法理解。我没有大量的SQL经验。所以我需要一些帮助

我有一张桌子XXX:

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

用英语说我想要的是:

选择“财务”中的所有SSN和名称,其中“IT”中的SSN名称不同。

我的工作没有尝试:

选择ssn,来自XXX的名称,其中org =“财务”,名称不在(从XXX选择名称,其中org =“IT”和ssn = the_first_ssn)

请帮忙。


我决定让它变得更难一点。

SSN可以在“IT”中多次出现:

所以我想在财务中选择SSN不存在的所有SSN和名称,并在“IT”中使用相同的名称

4 个答案:

答案 0 :(得分:3)

您可以在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
        )

子查询说IT中必须有一行具有相同的SSN但名称不同。

答案 1 :(得分: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
)

答案 2 :(得分: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'

答案 3 :(得分:0)

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

  1. 我的仅SQL Server查询使用CTE和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 solutionEXISTS子句中使用相关子查询:

    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 solutionIN子句中使用相关子查询:

    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)
            )
    
  5. 我将所有这些插入到SQL Server中,结果是查询1和2都生成相同的查询计划,查询3和4生成相同的查询计划。两组之间的差异是前一组实际上在内部执行INNER JOIN,而后一组实际上是左半连接。 (See here用于解释不同类型的连接。)

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

    所以考虑到这一切,我倾向于解决方案2,因为性能与3和4非常相似,而且它也比那些更灵活。我的解决方案使SELECT语句非常容易阅读,但它比2更冗长,而不是可移植的。我想如果你必须对两个“子表”中的每一个进行额外的过滤,或者如果这个查询的结果将用作进一步目标的中间步骤,那么我的可读性可能更好。