SQL IN子句替换临时表

时间:2016-11-25 09:45:44

标签: sql sql-server-2008

我的查询是:

Select * 
from Person 
where KV_CODE IN('','',''......1000 values here)

如何在临时表中写入此值列表,以便我可以用连接替换IN子句以提高性能。

此值列表基于用户的随机选择,并存储在Java集合中。

4 个答案:

答案 0 :(得分:0)

select *
from Person
where KV_CODE in (
    select KV_CODE
    from TempTable
)

这会将Person的KV_CODE与TempTable的KV_CODE进行比较。如果有匹配,它将与它们相交,这意味着您的第一个选择将仅打印那些行。

select *
from Person p
join TempTable tmp
on p.KV_CODE = tmp.KV_CODE

这将连接两个表并显示两个表中的匹配行。

除非你的问题是"如何从java集合填充临时表"

答案 1 :(得分:0)

Select * from Person P INNER JOIN #Temp T ON T.KV_CODE = P.KV_CODE 

您可以在临时表上应用INNER JOIN,类似于普通表。

答案 2 :(得分:0)

较新的数据库解决方案已经优化了这一点。 IN子句和Join之间没有太大区别,因为优化器会计算出这个方面并通过适当的路径执行查询。

如果您仍然希望,这就是您必须做的。 如果您使用的是Oracle,

  1. 您可以创建会话范围或事务范围临时表。
  2. 将数据插入此临时表
  3. 火灾查询
  4. SELECT * 
    FROM PERSONS T1, 
         TEMP_TABLE_NAME_HERE T2 
    WHERE T1.KV_CODE = T2.KV_CODE
    

    但是,更好的解决方案是避免在运行时创建临时表。实际上,您可以在应用程序数据库中创建一个永久表,其中包含一些用于标识会话的唯一键(用于隔离交叉会话影响,即使用相同功能的2个用户)。

    CREATE TABLE KV_TEMP_TABLE 
    (SESSION_ID VARCHAR2(100), 
    KV_CODE VARCHAR2(100)
    );
    

    - 适当调整数据类型

    然后您的查询应该是

    SELECT * FROM PERSONS T1, KV_TEMP_TABLE T2 
    WHERE T2.SESSION_ID = ? 
    AND T1.KV_CODE = T2.KV_CODE
    

    - 绑定您的会话ID 在发出此查询之前,您必须使用普通插入语句(以及会话ID)将数据填充到KV_TEMP_TABLE

答案 3 :(得分:0)

使用此示例填充临时表:

DECLARE @t TABLE
(
EmployeeID INT,
Certs VARCHAR(8000)
)
INSERT @t VALUES (1,'B.E.,MCA, MCDBA, PGDCA'), (2,'M.Com.,B.Sc.'), (3,'M.Sc.,M.Tech.')

SELECT EmployeeID,
LTRIM(RTRIM(m.n.value('.[1]','varchar(8000)'))) AS Certs
FROM
(
SELECT EmployeeID,CAST('<XMLRoot><RowData>' + REPLACE(Certs,',','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x
FROM   @t
)t
CROSS APPLY x.nodes('/XMLRoot/RowData')m(n) 

填充临时表@t后,可以与JOIN一起使用以获得所需的输出。