简体   繁体   中英

Rewrite query without using temp table

I have a query that is using a temp table to insert some data then another select from to extract distinct results. That query by it self was fine but now with entity-framework it is causing all kinds of unexpected errors at the wrong time.

Is there any way I can rewrite the query not to use a temp table? When this is converted into a stored procedure and in entity framework the result set is of type int which throws an error:

Could not find an implementation of the query pattern Select not found.

Here is the query

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;

First, a full join makes no sense in the first query. You are selecting only columns from the first table, so you need that.

Second, you can use a CTE.

Third, you should be able to get rid of the SELECT DISTINCT by using an EXISTS condition.

I would suggest:

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
             );

No need for anything fancy, you can just replace the reference to #temp with an inner sub-query containing the query that generates #temp eg

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: I haven't made any effort to improve the query overall like Gordon has but do consider his suggestions.

You can use CTE instead of the temp table:

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
;

This query will return the same results as your original query with the temp table, but its performance may be quite different; not necessarily slower, it can be faster. Just something that you should be aware about.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM