慢查询性能和错误疑难解答 - Where子句在@Table SQL Server 2012中查找值

时间:2016-01-13 15:54:22

标签: sql sql-server sql-server-2012

我的查询是多个部分。我获得了某些信息,并使用DECLARE @TABLENAME TABLE()将其放入表中,然后我直接在其下面有一个查询,其中有一个看起来像这样的where子句

WHERE a.PatientAccountID IN (
    SELECT Encounter
    FROM @TOC
)

在这个查询中@TOC.Encounter = A.PatientAccountID,所以我的理解是这个查询只会查看来自@TOC表的遭遇。情况并非如此,所以我假设有一个完整的表加载,然后使用where子句。我理解正确吗?我应该把那个where子句放在JOIN上面吗?我知道这不符合我的想法,因为我必须添加

AND A.PatientAccountID NOT IN (
    '12345678910', '99990000999'
)

以防止错误。

更新

我将联接更改为此(错误仍然存​​在)

FROM smsmir.sc_patientvisit                   AS A
    LEFT OUTER JOIN smsdss.QOC_vst_summ_v    AS B
    ON a.PatientAccountID = b.episode_no
        --test
        AND a.PatientAccountID IN (
            SELECT Encounter
            FROM @TOC
        )
    LEFT OUTER JOIN...

更新2

我检查了@TOCEncounter列,该表中不存在1234567891099990000999的有问题的数字。我尝试过使用

WHERE a.PatientAccountID IN (
    SELECT t.Encounter
    FROM @TOC t
)

WHERE EXISTS (
    SELECT T.Encounter
    FROM @TOC T
    WHERE T.Encounter = A.PatientAccountID
)
到目前为止,两者都无济于事......还奇怪的是,当我做以下事情时

SELECT t.Encounter
FROM @TOC t

违规遭遇id不会出来,但是当我这样做时

SELECT t.Encounter
FROM @TOC t
WHERE t.Encounter = '12345678910'

我得到了varchar转换错误,因为@TOC.Encounter的类型为INT所以我想最初由@GordonLinhoff定义我的错误就在那里。

谢谢,

2 个答案:

答案 0 :(得分:2)

[编辑]根据您获得的错误和新信息判断,在将PatientAccountIDEncounter进行比较时,您需要将CONVERT(INT, @Val)强制转换为INT。这可以通过cast(@Val as INT)IN来完成。

a.PatientAccountID子句与子查询一起使用时,子查询将返回所有内容,即使找到了EXISTS,所以是的,你是正确的,正在发生一个完整的表加载。如果您想最小化表负载,那么您可以将其更改为WHERE EXISTS ( SELECT t.Encounter FROM @TOC t WHERE t.Encounter = CONVERT(INT, a.PatientAccountID) ) ,如下所示:

INNER JOIN

一旦找到匹配项,这将退出子查询,这使得此选项更适合您的修复。

作为旁注,您还可以在@TOCEncounter进行PatientAccountID,其加入条件与FROM smsmir.sc_patientvisit AS a LEFT OUTER JOIN smsdss.QOC_vst_summ_v AS b ON a.PatientAccountID = b.episode_no INNER JOIN @TOC AS t ON CONVERT(INT, a.PatientAccountID) = t.Encounter 匹配character.only=TRUE,如下所示:

library

答案 1 :(得分:2)

评论太长了。你能试试这个版本吗?

WHERE a.PatientAccountID IN (
    SELECT t.Encounter
    FROM @TOC t
)

一种可能性是@TOC中的列实际上并未被称为Encounter - 可能是轻微的拼写错误。如果没有限定列名,SQL将从外部作用域中的表中获取该字段 - 该字段和患者ID可能始终相等。这可以解释没有过滤的事实。

无论如何,总是使用合格的列名来避免混淆是个好主意。

这只是一个想法。