Click here to Skip to main content
15,892,839 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I've ran in to yet another brick wall when it comes to SQL, this time I'd like to extend a query which I've inherited to add some more functionality.

I'm not sure if it's the possible to do this in the way I've tried to go about solving this but I've tried to add this new requested data as a sub query in the select statement.

Here is what I want to add to my query. From the id in the table fcontainer I've got to do this little walk to reach a product name.

SQL
select produkter.Produktnamn 
from FContainer INNER JOIN
                  Stämplingar ON FContainer.id = Stämplingar.ID INNER JOIN
                  Tempo ON Stämplingar.temponr = Tempo.temponr INNER JOIN
                  Produkter ON Tempo.produktnr = Produkter.Produktnr


The query which I wish to extend contains fcontainer but only in another sub query.

SQL
SELECT FContainerHylla.Name, FContainerPlats.HyllId,
       FContainerPlats.x, FContainerPlats.y,
       FContainerPlats.enable, FContainerHylla.Type,
       ISNULL((SELECT MIN(fcontainer.id) AS id
           FROM FContainer
           WHERE (PlatsId = FContainerPlats.id)), 0) AS FcId
FROM FContainerPlats INNER JOIN FContainerHylla ON 
     FContainerPlats.HyllId = FContainerHylla.Id
WHERE (FContainerHylla.Type IN (1, 6, 10))
ORDER BY FContainerPlats.HyllId, FContainerPlats.x, FContainerPlats.y



So far my best results is by adding the first query inside the select statement surrounded by ( ) to form a sub query but I get an error where I'm not allowed to have more than one value in a sub query.

I need to reduce the possible data by adding a where clause and I'd like to add
SQL
where fcontainer.id = ....


I need fcontainer.id to be compared to the value returned from the isnull statement and defined AS id but not certain how to do this.
Posted

1 solution

You can JOIN onto a sub query rather than having it in the select. I came up with this but I can't test it
SQL
SELECT FContainerHylla.Name, FContainerPlats.HyllId,
       FContainerPlats.x, FContainerPlats.y,
       FContainerPlats.enable, FContainerHylla.Type,
       ISNULL((SELECT MIN(fcontainer.id) AS id
           FROM FContainer
           WHERE (PlatsId = FContainerPlats.id)), 0) AS FcId

		,SubQ.Produktnamn
		   
FROM FContainerPlats 
INNER JOIN FContainerHylla ON FContainerPlats.HyllId = FContainerHylla.Id

INNER JOIN (SELECT FContainer.id AS SubID, produkter.Produktnamn AS Produktnamn
			from FContainer INNER JOIN
                  Stämplingar ON FContainer.id = Stämplingar.ID INNER JOIN
                  Tempo ON Stämplingar.temponr = Tempo.temponr INNER JOIN
                  Produkter ON Tempo.produktnr = Produkter.Produktnr) SubQ ON SubQ.SubID = FContainerPlats.id

WHERE (FContainerHylla.Type IN (1, 6, 10))
ORDER BY FContainerPlats.HyllId, FContainerPlats.x, FContainerPlats.y

I might have the key on the inner join to "SubQ" wrong.

Alternatively you could set them up as two Common Table Expressions and join them that way (again this is untested and watch out for the id I've used in the join)
;WITH CTE1 AS
(
	SELECT FContainerHylla.Name, FContainerPlats.HyllId,
		   FContainerPlats.x, FContainerPlats.y,
		   FContainerPlats.enable, FContainerHylla.Type,
		   ISNULL((SELECT MIN(fcontainer.id) AS id
			   FROM FContainer
			   WHERE (PlatsId = FContainerPlats.id)), 0) AS FcId

	FROM FContainerPlats 
	INNER JOIN FContainerHylla ON FContainerPlats.HyllId = FContainerHylla.Id
	WHERE (FContainerHylla.Type IN (1, 6, 10))
),
CTE2 AS 
(
	SELECT FContainer.id AS SubID, produkter.Produktnamn AS Produktnamn
	from FContainer 
		INNER JOIN Stämplingar ON FContainer.id = Stämplingar.ID 
		INNER JOIN Tempo ON Stämplingar.temponr = Tempo.temponr 
		INNER JOIN Produkter ON Tempo.produktnr = Produkter.Produktnr
) 
SELECT CTE1.*, CTE2.Produktnamn
FROM CTE1
INNER JOIN CTE2 ON CTE2.SubID = FContainerPlats.id
ORDER BY FContainerPlats.HyllId, FContainerPlats.x, FContainerPlats.y
 
Share this answer
 
v2
Comments
Member 11683251 10-Jun-15 6:38am    
I was just trying to solve this using CTE as it seems to be such a wonderful tool as you showed a while back in answer to another question but didn't think of doing it on the new query too. Your solution works with the minor adjustment where you joined the two tables where it should be CTE2.subId = CTE1.fcid and the table names in the order by should be CTE1.

The first answer where you join on to sub queries is error free but doesn't return anything but I'll check through it too since that seems so closer to what I was trying to do.

I thank you for taking the time to write this helpful answer, going to bookmark this one too.
CHill60 10-Jun-15 7:10am    
I've probably got the ON clause wrong or have picked up the wrong id in the sub-query.
I do like CTEs (you may have guessed!), but I do have a habit of becoming blinkered - it's often the first thing I reach for when sometimes a CASE in the order by clause will be more appropriate (for example) - not in this case but one to watch out for if you start to like CTE more and more :-)
Member 11683251 10-Jun-15 7:45am    
The two solutions differ slightly in the results I get, the CTE one returns slightly more than the other but what I noticed is that both do is return a lot of duplicate records.

The original query returns about 2500 records while these between 1700-1800 and that is with duplicates.

Take the CTE for example, running just CTE1 returns a set of 2500 records and CTE2 6600. So far it's exactly as expected.

I cant wrap my head around how the part which joins those two tables can manage to give me so many fewer records and with duplicates, some row triplicate or more. The way I interpret it is that we are referencing CTE2 and if we find a match with the id's we basically append the name. Not really what's happening but how I picture it in my head.

Here are the changes I made.

SELECT CTE1.*, CTE2.Produktnamn
FROM CTE1
INNER JOIN CTE2 ON CTE2.SubID = CTE1.FcId
ORDER BY CTE1.HyllId, CTE1.x, CTE1.y

It feels like learning to program all over again trying to learn sql, or rather more than just the basics.
CHill60 10-Jun-15 8:16am    
Try SELECT TOP 1 FContainer.id AS SubID, produkter.Produktnamn AS Produktnamn ... etc in the subquery or CTE2, I think I'm pulling back too much just to get the productname
Member 11683251 10-Jun-15 8:27am    
But wouldn't that just result in a single record selected?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900