Question

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?

Was it helpful?

Solution

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' 
    )
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top