I have a SQL query I'm having trouble creating using NHibernate Criteria:
SELECT ID, COLA, COLB, COLC
FROM table
WHERE COLC='something' AND ID IN (SELECT ID FROM (SELECT MAX(ID) as ID, COLA FROM table WHERE COLB='something' GROUP BY COLA) subquery)
ORDER BY ID DESC
I originally had this slightly simpler query:
SELECT ID, COLA, COLB, COLC
FROM table
WHERE COLC='something' AND ID IN (SELECT MAX(ID) FROM table WHERE COLB='something' GROUP BY COLA)
ORDER BY ID DESC
However, with NHibernate, if I use a "GROUP BY", it automatically adds the field to the SELECT statement, and I have no way of stopping it (as far as I can find).
Basically, I need to find the latest record grouped by some arbitrary column (in this example, "COLA"). I'm selecting the maximum ID to try to get the latest record (though this could be something else, like "MAX(UPDATED)"). After getting the set of latest records, I'm further filtering them ("WHERE COLC='something'"), and selecting the columns I need in the result.
If there's a better way to get the same results, I'd be glad to hear it. My SQL skills are mediocre, at best.
In NHibernate, I could get the two queries right, but the piece in the middle - "SELECT ID FROM", wouldn't work.
The main query:
DetachedCriteria.For<table>()
.Add<table>(x => x.COLC == "something")
.Add(LambdaSubquery.Property<table>(x => x.ID).In(subquery));
And the subquery:
DetachedCriteria.For<table>()
.Add<table>(x => x.COLB == "something")
.SetProjection(Projections.ProjectionList()
.Add(LambdaProjection.Max<table>(x => x.ID))
.Add(LambdaProjection.GroupProperty<table>(x => x.COLA)));
The subquery criteria puts "COLA" in the select list (because of the GroupProperty), so it's unusable on its own, and that's why I need to figure out how to do the "SELECT ID FROM (SELECT ..." in the criteria. When combined, they produce the following invalid SQL (because the subquery returns more than one column):
SELECT ID, COLA, COLB, COLC
FROM table
WHERE COLC='something' AND ID IN (SELECT MAX(ID), COLA FROM table WHERE COLB='something' GROUP BY COLA)
ORDER BY ID DESC
Edit: It might also help to see the kind of data and results I want:
ID COLA COLB COLC
1 1 someone someother
2 1 something someone (Matches subquery, but not the max. ID)
3 1 something something (Matches subquery and main query)
4 2 someone something
5 2 something someother (Only matches subquery)
6 3 someone someother
The result I want here are the maximum ID for a given set of "COLA"s, where "COLB" matches "something", so I'd want the subquery to return {3, 5}. In the end, the query would only return the record for ID 3 (the outer WHERE clause weeds out the 5 because COLC is wrong). The actual data in COLB and COLC is irrelevant - I'm just using that to further filter the results.
I think, at the core of it, I want the latest record (max ID) for each set of COLA
SELECT ID, COLA, COLB
FROM table
WHERE ID IN (SELECT MAX(ID) FROM table GROUP BY COLA)
ORDER BY ID DESC