Search code examples
sqlarrayssql-serverselect

How to store SQL query result into variable to include in a later SELECT statement


I have this SQL query:

SELECT MAX(a.date), d.group, c.name, b.name_id 
FROM table1 a
LEFT JOIN table2 b ON a.id = b.id
LEFT JOIN table3 c ON b.name_id = c.name_id
LEFT JOIN table4 d ON b.group_id = d.group_id
WHERE a.foo = '12345'
GROUP BY d.group, c.name, b.name_id
ORDER BY MAX(a.date)

It returns something like this:

date group name name_id
yyyy-mm-dd 00:00:00 FOOFOO FA FA 1
yyyy-mm-dd 00:00:00 FOOFOO FA FA 2
yyyy-mm-dd 00:00:00 FOOFOO FA FA 3
yyyy-mm-dd 00:00:00 FOOFOO FA FA 4
yyyy-mm-dd 00:00:00 FOOFOO FA FA 5

Focusing on name_id, I want to take all of them (about 800) and store them into an array-like variable. Then utilize said array-like variable in the following type of clause in separate SELECT statement:

SELECT COUNT(a.id) 
FROM table999 a
WHERE a.foofoo IN @array

I've seen that you can build temporary tables that act as arrays, but I'm not sure if that's exactly what I'm looking for. I've also read that you can utilize variables (via @var) but it seems those can only hold one piece of data. Can what I'm looking for be done in SQL? Is there an array-like variable where I can push these name_id's to? Any help is super appreciated!


Solution

  • I would suggest using an EXISTS here. You can also simplify your initial query as a result. You don't need table3 and table4 as these don't filter the data, and so would only slow the query down.

    You just an INNER JOIN between tables table1 and table2. This can be changed to an INNER JOIN as you want t2.name_id to have a non-NULL value, which means that the JOIN must be true (though I do assume that name_id itself isn't NULLable).

    This gives you the following query instead:

    SELECT COUNT(a.id)
    FROM dbo.table999 t999
    WHERE EXISTS(SELECT 1
                 FROM dbo.table2 t2
                      JOIN dbo.table1 t1 ON t2.id = t1.id
                 WHERE t1.foo = '12345'
                   AND t2.name_id = t999.foofoo);
    

    There's little need to a table variable here (what you call an "array", which SQL Server doesn't have), as this would just be an additional cost to run the first query (with all its additional JOINs), store that data somewhere (which might be in RAM, but could be in a table in tempdb), and then read that data back.