NHibernate HQL Group by Entity - nhibernate

Is it possible to run a query similar to this one in HQL without having to specify all of the column names.
select med, MAX(med.PrescriptionLines.Prescription.PrescriptionDate)
from Medication med
where med.Patient.PatientId = :patientId
group by med
This query expands out all of the properties of the Medication object in the select, but in the group by only expands med to be med.MedicationId. I don't want to have to specify all of the properties of the medication object in the group by clause. Is there a way to do it?
I've tried replacing the group by med with group by med.* or group by {med.*} but that doesn't work.
Any ideas?

It's not implemented. See:
https://nhibernate.jira.com/browse/NH-528
http://opensource.atlassian.com/projects/hibernate/browse/HHH-1615 (this issue is over three years old)

Related

SQL Group on a combination of values

I'm working a DB design regarding how a user launched something.
My idea was to have timestamp (DateTime) column, and a method column (varchar).
This 'method' (varchar) could be anything:
BUTTON_OK
BUTTON_X
APP_Y
APP_Z
etc
How can I COUNT the uses but group some values. In this case I want to have my result:
BUTTONS: 20
APP_X: 10
APP_Z: 14
You need some way of defining which 'methods' fall into which 'method group'.
One way would be to have a lookup table:
tbl_methodgroup
method_id Method Method_group
1 Button_OK Buttons
2 Button_X Buttons
3 App_Y App_Y
4 App_Z App_Z
then you could use:
select
b.method_group,
count(1)
from
tbl_methodgroup a
inner join tbl_method b on a.Method=b.Method
group by b.method_group
This method would have the advantage of being scalable as more methods get added. Rather than hand coding queries, which would need to be modified each time.
If the name of the table is tblTest, then the query will look like following:
SELECT method, COUNT(*) FROM tblTEst Group BY method
Apologies if I missread question, last chance to make it right if you have consistency in the data and grouping scenarios you can do following:
SELECT LEFT(method,CHARINDEX('_',method)-1),
COUNT(*)
FROM tblTest
GROUP BY LEFT(method,CHARINDEX('_',method)-1)
Otherwise Stuart Moore's answer is correct one.

Problems with distinct in SQL query

Okay, i've been trying it for a while and haven't succeeded yet, it's kind of mystical, so please help.
Here is my table. I need to select all distinct models and group/order them by the vehicle_type. Everything is ok until I start using DISTINCT.
I'm using postgres
Little help with query please?
Assuming model could be shared between several vehicle types:
SELECT vehicle_type,model
FROM vehicle
GROUP BY vehicle_type,model
ORDER BY vehicle_type,model
The data model does not adequately capture your reporting requirments as the column data needs to be inspected to categorise it but something like:
(Extrapolating a possible relationship from your description)
SELECT CASE (vt.description ~ 'car$')
WHEN TRUE THEN 'car'
ELSE 'van'
END AS vehicle_group,
vt.description AS vehicle_sub_group,
COUNT (*) -- or whatever aggregates you might need
FROM vehicle v
INNER JOIN vehicle_type vt ON vt.vehicle_type = v.vehicle_type
GROUP BY 1,2;
Might get you towards what you need in the stated case, however it is a fragile way of dealing with data and will not cope well with additional complexities e.g. if you need to further split car into saloon car, sports car, 4WD or van into flatbed, 7.5 ton, 15 ton etc.

SQL count query not working

I have problem with this query:
SELECT Ordre.Objet, Count(Ordre.Objet) AS CompteDeObjet
FROM Ordre INNER JOIN Avis ON Ordre.[Ordre SAP] = Avis.[Ordre SAP]
GROUP BY Ordre.Objet, Avis.[Date Appel], Ordre.Objet
HAVING (((Avis.[Date Appel])>#8/1/2011# And (Avis.[Date Appel])<#10/20/2011#) AND ((Ordre.Objet) Is Not Null));
That I generated using Access 2003. it should count the number of items of each kind in the Object column but it only shows a count of one per different item...
Can't seem to figure out how to make this work.
[EDIT]
Considering the first two answers, I changed my code to the following, but I still get the same result:
SELECT Ordre.Objet, Count(Ordre.Objet) AS CompteDeObjet
FROM Ordre INNER JOIN Avis ON Ordre.[Ordre SAP] = Avis.[Ordre SAP]
WHERE (((Avis.[Date Appel])>#8/1/2011# And (Avis.[Date Appel])<#10/20/2011#) AND ((Ordre.Objet) Is Not Null))
GROUP BY Ordre.Objet;
[EDIT #2]
here is a sample of my data:
Ordre SAP Objet
11147212 Simplex
11147214 Simplex
11147215 Simplex
11147216 Simplex
11147225 Simplex
11147240 Auto Level
11147243
11147247 CANOPY
11147259 Capteur
And here is what the query from the last edit gives me:
Auto Level 1
CANOPY 1
Capteur 1
Simplex 1
All of my data is included in the date range specified in the query.
Sorry, i don't know how to show this in a proper table, I'm new here...
The query will give one row / count per item you GROUP BY.
You are grouping on:
GROUP BY Ordre.Objet, Avis.[Date Appel], Ordre.Objet
So, you will get one cound for each Objet / Date Appel combination
Try moving what is in the HAVING clause to the WHERE clause. HAVING filters on grouped items, it may be stopping the query from counting the items properly.
Ok, so I figured out what my problem was:
I have way more Ordres than I have Avis and not all avis have an ordre attached. My query somehow only counts the objects that have an Avis attached to it (because of the JOIN clause?)
so while testing, I just randomly placed lots of different values to random record in the order table. it just so happened that I put one of each on Ordres that had corresponding Avis...
Silly me :)
Thanks everyone though, help is always apreciated

How to write the following SQL query in NHibernate

Hey - I'm battling to figure out how to write the following using NHibernate ICriteria (Multi criteria?) for the following:
(It's a query to get a list of first names ordered by popularity in the table in the last day)
select firstname,count(firstname) as occurances from registrants
where timestamp between DateAdd(day,-1, GetDate()) and getdate()
group by firstname
order by count(firstname) desc
Also, given this is just a couple of columns from a table, excluding the ID, and NHibernate needs ID's for it's objects, what's the easiest way to "fake" an ID so I can just get the results?
You need to use projections and a transformer to do this. Here's some background info http://nhibernate.info/doc/nh/en/index.html#querycriteria-projection
var criteria = Session.CreateCriteria<Registrant>()
.Add(Restrictions.Between("Timestamp", DateTime.Now.AddDays(-1), DateTime.Now)
.AddOrder(Order.Desc(Projections.Count("FirstName")))
.SetProjection(Projections.ProjectionList()
.Add(Projections.GroupProperty("FirstName"), "FirstName")
.Add(Projections.Count("FirstName"), "Occurances")
.SetResultTransformer(Transformers.AliasToBean<FirstNameOccurance>());
criteria.List<FirstNameOccurance>();
You'll need to create a class called FirstNameOccurance that has 2 properties called FirstName and Occurances.

Group by SQL statement

So I got this statement, which works fine:
SELECT MAX(patient_history_date_bio) AS med_date, medication_name
FROM biological
WHERE patient_id = 12)
GROUP BY medication_name
But, I would like to have the corresponding medication_dose also. So I type this up
SELECT MAX(patient_history_date_bio) AS med_date, medication_name, medication_dose
FROM biological
WHERE (patient_id = 12)
GROUP BY medication_name
But, it gives me an error saying:
"coumn 'biological.medication_dose' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.".
So I try adding medication_dose to the GROUP BY clause, but then it gives me extra rows that I don't want.
I would like to get the latest row for each medication in my table. (The latest row is determined by the max function, getting the latest date).
How do I fix this problem?
Use:
SELECT b.medication_name,
b.patient_history_date_bio AS med_date,
b.medication_dose
FROM BIOLOGICAL b
JOIN (SELECT y.medication_name,
MAX(y.patient_history_date_bio) AS max_date
FROM BIOLOGICAL y
GROUP BY y.medication_name) x ON x.medication_name = b.medication_name
AND x.max_date = b.patient_history_date_bio
WHERE b.patient_id = ?
If you really have to, as one quick workaround, you can apply an aggregate function to your medication_dose such as MAX(medication_dose).
However note that this is normally an indication that you are either building the query incorrectly, or that you need to refactor/normalize your database schema. In your case, it looks like you are tackling the query incorrectly. The correct approach should the one suggested by OMG Poinies in another answer.
You may be interested in checking out the following interesting article which describes the reasons behind this error:
But WHY Must That Column Be Contained in an Aggregate Function or the GROUP BY clause?
You need to put max(medication_dose) in your select. Group by returns a result set that contains distinct values for fields in your group by clause, so apparently you have multiple records that have the same medication_name, but different doses, so you are getting two results.
By putting in max(medication_dose) it will return the maximum dose value for each medication_name. You can use any aggregate function on dose (max, min, avg, sum, etc.)