Skip to content
Advertisement

Trouble dealing with max() function in SQL Server

The whole code is part of a stored procedure. I have two pieces of code:

SELECT *
FROM eng
FULL JOIN ent ON eng.EntId = ent.EntId
FULL JOIN del ON del.EngId = eng.EngId
FULL JOIN cli ON cli.CId = ent.CId
WHERE eng.[Version] = (SELECT MAX([Version]) 
                       FROM eng b 
                       WHERE eng.EngId = b.EngId 
                         AND EntId = @EntId 
                       GROUP BY EngId)
  AND ent.[Version] = (SELECT MAX([Version]) 
                       FROM ent e 
                       WHERE ent.EntId = e.EntId 
                         AND EntId = @EntId 
                       GROUP BY EntId)
  AND ent.EntId = @EntityId

This one works fine. On the line

eng.[Version] = (SELECT MAX([Version]) FROM eng b ...

this particular code is producing the output:

No Column name
1
2

and the other one:

SELECT *  
FROM [dbo].[del] D WITH(NOLOCK)
FULL JOIN eng EG WITH(NOLOCK) ON EG.EngId = D.EngId
FULL JOIN [dbo].[ent] E WITH(NOLOCK) ON E.EntId = D.EntId
FULL JOIN [dbo].cli cli ON cli.CliId = E.CliId
WHERE D.[Version] = (SELECT MAX([Version]) 
                     FROM del d 
                     WHERE D.DelId = d.DelId 
                       AND EngId = @EngId 
                     GROUP BY DelId)
  AND EG.[Version] = (SELECT MAX([Version]) 
                      FROM eng eg 
                      WHERE EG.EngId = eg.EngId  
                        AND EngId = @EngId 
                      GROUP BY EngId)
  AND E.[Version] = (SELECT MAX([Version]) 
                     FROM ent e 
                     WHERE E.EntId = e.EntId 
                       AND EntId = @EntId 
                     GROUP BY EntId)
  AND D.EngId = @EngId

This is not working correctly. I get an error:

Subquery returned more than 1 value

on this line

D.[Version] = (SELECT MAX([Version]) FROM del d...

Independently it produces this output:

No column name
2
1

Column and table names are dummy. can someone help please?

Edit

Sample data

Eng table

EngID    EntID     Entname   Version
-------------------------------------
Mana1    333113    name1        1
Mana1    333113    name2        2

Del table

DelID     EntID     EngID    Delname      Version
-------------------------------------------------
D110      333113    Mana1    delname1        1
D110      333113    Mana1    delname2        2
D111      333113    Mana1    delnewname      1

I need to pull data from these 2 tables.

This is the output I need:

EntID     EngID    DelID    Entname   Delname    Version (from del table)
---------------------------------------------------------    
333113    Mana1    D110     name2     delname2    2
333113    Mana1    D111     name2     delnewname  1

Logic is pull latest version from eng table and map them to rows in del table and find the latest version there as well.

Advertisement

Answer

I think you have an typo in the following line

D.[Version] = (SELECT MAX([Version]) FROM del d WHERE D.DelId=d.DelId AND EngId = @EngId group by DelId)

where it reads WHERE D.DelId=d.DelId

You are comparing the same column from the same table,
so both queries are not doing the same thing.

EDIT

Since you do not believe me, I made a DBFiddle with your sample data.

I have your query, that returns the error,
and I have the query where I change the where clause I as said above, which works.

EDTI 2

In the comment you asked how this works, I will try to explain

your mainquery has an alias called D

select * FROM [dbo].[del] D

in your where clause you have a subquery, and in that subquery you also have an alias called d

FROM   del d WHERE  D.DelId=d.DelId

put together :

select * 
FROM [dbo].[del] D
  FULL JOIN eng EG ON EG.EngId = D.EngId
WHERE D.[Version] = (SELECT MAX([Version]) 
                     FROM   del d 
                     WHERE  D.DelId=d.DelId -- I think this is wrong
                     AND    EngId = @EngId 
                     group by DelId
                    )

So, what you probably expect is that the database takes the DelID from the subquery (alias d) and compares it with the DelId from the main query (alias D).

But that is not what is happening, because alias D and d are the same, the database does not looks for the value in the main query, because it has a d right here in the subquery.
You might just as well have written where 1=1
Therefor the group by finds 2 distinct rows (using your sample data) and thus returns 2 MAX values, hence the error.

What I did was give the subquery another alias `D2′ which means that the database will now compare the value from D.DelID with D2.DelID, which is what you want.

I hope this is clear now

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement