不使用临时表重写查询

时间:2019-12-17 02:24:11

标签: sql sql-server

我有一个查询,该查询使用临时表插入一些数据,然后从中进行另一个选择以提取不同的结果。这个查询本身很好,但是现在有了实体框架,它会在错误的时间导致各种意外错误。

有什么办法可以重写查询而不使用临时表?将其转换为存储过程后,在实体框架中,结果集的类型为int,将引发错误:

  

找不到查询模式的实现选择未找到。

这是查询

Drop Table IF EXISTS #Temp

SELECT 
    a.ReceiverID, 
    a.AntennaID,
    a.AntennaName into #Temp
FROM RFIDReceiverAntenna a
full join Station b ON (a.ReceiverID = b.ReceiverID) and (a.AntennaID = b.AntennaID) 
where (a.ReceiverID is NULL or b.ReceiverID is NULL) 
and (a.AntennaID IS NULL or b.antennaID is NULL)

select distinct r.ReceiverID, r.ReceiverName, r.receiverdescription
from RFIDReceiver r
inner join #Temp t on r.ReceiverID = t.ReceiverID;

3 个答案:

答案 0 :(得分:0)

首先,full join在第一个查询中毫无意义。您仅从第一张表中选择列,因此您需要这样做。

第二,您可以使用CTE。

第三,通过使用SELECT DISTINCT条件,您应该可以摆脱EXISTS

我建议:

WITH ra AS (
      SELECT ra.*
      FROM RFIDReceiverAntenna ra
           Station s
           ON s.ReceiverID = ra.ReceiverID AND
              s.AntennaID = ra.AntennaID)
      WHERE s.ReceiverID is NULL
     )
SELECT r.ReceiverID, r.ReceiverName, r.receiverdescription
FROM RFIDReceiver r
WHERE EXISTS (SELECT 1
              FROM ra
              WHERE r.ReceiverID = ra.ReceiverID
             );

答案 1 :(得分:0)

不需要任何花哨的内容,您只需用内部子查询替换对#temp的引用,该子查询就包含生成#temp的查询,例如

select distinct r.ReceiverID, r.ReceiverName, r.receiverdescription
from RFIDReceiver r
inner join (
    select 
        a.ReceiverID, 
        a.AntennaID,
        a.AntennaName
    from RFIDReceiverAntenna a
    full join Station b ON (a.ReceiverID = b.ReceiverID) and (a.AntennaID = b.AntennaID) 
    where (a.ReceiverID is NULL or b.ReceiverID is NULL) 
    and (a.AntennaID IS NULL or b.antennaID is NULL)
) t on r.ReceiverID = t.ReceiverID;

PS:我没有像Gordon那样努力改善整体查询,但确实考虑了他的建议。

答案 2 :(得分:0)

您可以使用CTE代替临时表:

WITH
CTE
AS
(
    SELECT 
        a.ReceiverID, 
        a.AntennaID,
        a.AntennaName
    FROM 
        RFIDReceiverAntenna a
        full join Station b 
            ON (a.ReceiverID = b.ReceiverID) 
            and (a.AntennaID = b.AntennaID) 
    where 
        (a.ReceiverID is NULL or b.ReceiverID is NULL) 
        and (a.AntennaID IS NULL or b.antennaID is NULL)
)
select distinct 
    r.ReceiverID, r.ReceiverName, r.receiverdescription
from 
    RFIDReceiver r
    inner join CTE t on r.ReceiverID = t.ReceiverID
;

此查询将返回与使用temp表的原始查询相同的结果,但其性能可能会有所不同;不一定慢,也可以更快。只是您应该注意的事情。

相关问题