【问题标题】:SQL subquery matches hard-coded IN criteria, but not subquerySQL 子查询匹配硬编码的 IN 条件,但不匹配子查询
【发布时间】:2011-04-28 04:25:03
【问题描述】:

我有一群人参加了考试。我可以用这个查询选择他们的 ID:

SELECT person_id
FROM tests
WHERE test_code = 1234

我想从人口统计表中提取这些人的记录,所以我尝试了这个子查询:

SELECT *
FROM demographics d
WHERE d.person_id IN (
    SELECT t.person_id
    FROM tests t
    WHERE t.test_code = 1234
)

...但我没有得到任何结果。如果我从(功能)子查询中获取几个 ID 并将它们硬编码到 IN 标准中:

SELECT *
FROM demographics d
WHERE d.person_id IN (01123, 58132)

...查询有效。我必须在这里遗漏一些非常基本的东西 - 你知道它是什么吗?

可能的复杂因素:t.person_id 是 char13,d.person_id 是 varchar50。这是 MS SQL Server 9.0.4035;我在 SQL Server Management Studio 工作。

【问题讨论】:

    标签: sql sql-server-2005 subquery in-subquery


    【解决方案1】:

    问题可能在于 TESTS.PERSON_ID 的结尾带有空格,因为它被声明为 CHAR 而不是 VARCHAR。我不确定如何在 SQL Server 中删除尾随空格(我已经有一段时间没有使用它了),但在 Oracle 中我会使用 TRUNC 函数,如

    SELECT * 
      FROM demographics d 
      WHERE d.person_id IN ( 
        SELECT TRUNC(t.person_id )
          FROM tests t 
          WHERE t.test_code = 1234 ) 
    

    编辑:我相信 SQL Server 中的等效函数是 RTRIM。

    【讨论】:

    • Oracle:TRUNC(t.person_id) SQL:LTRIM(RTRIM(t.person_id))
    • @Vidar, @ig0774:我查了一下,你们都是对的; LTRIM(RTRIM(...)) 相当于 Oracle 的 TRUNC,但 RTRIM 是真正需要的。谢谢。 :-)
    • 我相信这个问题。 SQL Server 修剪函数是 LTRIM 和 RTRIM。尝试使用 ('01123', '58132') 作为 IN 子句的参数的硬编码查询进行验证。
    • 其实是前导零。人口统计 ID 的前面都有三个零……嗯。但这让我想到了正确的事情。谢谢!
    【解决方案2】:
    SELECT * 
    FROM demographics d 
    WHERE d.person_id IN ( 
        SELECT person_id 
        FROM tests 
         WHERE test_code = 1234 
    ) 
    

    你试过不带 t.在子查询中?在查看您的原始子查询时,您没有给表测试一个别名 t...

    【讨论】:

    • 是的,我已经验证了子查询按书面形式工作(咳咳,这与我在这里写的不完全一样 - Larry 在我的表别名中发现了一个错字)。
    【解决方案3】:

    我从来没有在 IN 子句中尝试过子查询,所以我不能保证这可行,但试试这个:

    SELECT * 
    FROM demographics d 
    WHERE d.person_id IN ( 
        (SELECT t.person_id 
        FROM t.tests 
        WHERE t.test_code = 1234) 
    ) 
    

    我只是在您的子查询周围添加了括号,这是常见的做法。同样,我从来没有在 IN 子句中尝试过 subq,所以不能保证它有效,但值得一试。

    【讨论】:

      【解决方案4】:

      首先,您没有正确地对测试进行别名。应该是:

      SELECT *
      FROM demographics d
      WHERE d.person_id IN (
          SELECT t.person_id
          FROM **tests t**
          WHERE t.test_code = 1234
      )
      

      其次,如果 t.person_id 返回任何 NULL,您将不会得到任何结果。

      【讨论】:

      • NULL 仅对 NOT IN 有此影响
      • 抱歉,这只是一个错字。不过,非常注重细节。
      • @Martin — 谢谢,我的立场是正确的。我最常使用的数据库没有根据 SQL 标准实现 NULL 问题,我通常很欣赏这一点。直到最近,SQLite3 还在做同样的事情。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多