Getting a List of IDs from a Table with Group Concat as a variable to uise for IN clause
-
23-06-2021 - |
Pregunta
I have a table of locations
and a table of stockLevels
. I working on a complex query to tell me items which have been in stock for a long time, which location they're in and a few other things all in one hit.
Part of it is giving me inaccurate results though.
... LEFT JOIN ...
SELECT id, sum(stockLevel) as totalStockLevel FROM stockLevels
WHERE stockLocation IN
((SELECT
GROUP_CONCAT(CONVERT(id, CHAR(8))) as idList
FROM `locations` WHERE `isThirdParty` = '0'
AND `pickFrom`='1'
GROUP BY pickFrom))
GROUP BY id)
ourStock ON ourStock.id=products.id
... MORE OF QUERY ....
This is a snippet of the whole query, the inner SELECT
works in isolation, but it's not applying the list of IDs into the IN clause, seems to just read the first one.
So, to explain more clearly.
The inner SELECT
:
SELECT
GROUP_CONCAT(CONVERT(id, CHAR(8))) as idList
FROM `locations` WHERE `isThirdParty` = '0'
AND `pickFrom`='1'
GROUP BY pickFrom
Return a comma separated list value as a column named idList
, the value being 1,2,10,11
This query works.
If I manually use that comma separated list in the original query, it also works, ie:
... LEFT JOIN ...
SELECT id, sum(stockLevel) as totalStockLevel FROM stockLevels
WHERE stockLocation IN
(1,2,10,11)
GROUP BY id)
ourStock ON ourStock.id=products.id
... MORE OF QUERY ....
No errors are generated by this code, but the results it produces are that of this query:
... LEFT JOIN ...
SELECT id, sum(stockLevel) as totalStockLevel FROM stockLevels
WHERE stockLocation IN
(1)
GROUP BY id)
ourStock ON ourStock.id=products.id
... MORE OF QUERY ....
So, I'm not getting the comma separated list generated by the inner query being injected into the IN clause of the outer query.
Can anyone advise why?
Solución
IN()
expects a list of values or a subquery, but you are giving it a varchar. You migh try to join stockLocation and Locations to produce desired results:
SELECT stockLevels.id,
sum(stockLevels.stockLevel) as totalStockLevel
FROM stockLevels
INNER JOIN locations
ON stockLevels.stockLocation = locations.id
AND locations.isThirdParty = '0'
AND locations.pickFrom = '1'
GROUP BY stockLevels.id
Of course, you might eliminate group_concat to get the same effect:
WHERE stockLocation IN
(SELECT id
FROM `locations`
WHERE `isThirdParty` = '0'
AND `pickFrom`='1'
)