NHibernate use Criteria for Count(),First() - nhibernate

I have a question about Criteria method, one-to-many relation to the database, 'one' is "account", 'many' is "sites", when I use CreateCriteria() something is not right.
Like this: SessionFactory.OpenSession().CreateCriteria(typeof(Account)).List().Count();
Before it's run, I think the SQL should be SELECT COUNT(*) FROM table, but the SQL is SELECT id, siteurl...FROM table. So what's wrong with this? How can I solve it?
And First() method should be SELECT TOP1 ...FROM table, but it is SELECT ...FROM table
I'm an Nhiberate rookie, Please help me.

This happens because the Count method you are calling at the end executes after the query has run and outside of the database. You are only counting the elements in the list in memory. To achieve what you are looking for you could use a projection:
var count = session
.CreateCriteria<Account>()
.SetProjection(
Projections.Count(Projections.Id())
)
.UniqueResult<long>();

Related

Get count and result from SQL query in Go

I'm running a pretty straightforward query using the database/sql and lib/pq (postgres) packages and I want to toss the results of some of the fields into a slice, but I need to know how big to make the slice.
The only solution I can find is to do another query that is just SELECT COUNT(*) FROM tableName;.
Is there a way to both get the result of the query AND the count of returned rows in one query?
Conceptually, the problem is that the database cursor may not be enumerated to the end so the database does not really know how many records you will get before you actually read all of them. The only way to count (in general case) is to go through all the records in the resultset.
But practically, you can enforce it to do so by using subqueries like
select *, (select count(*) from table) from table
and just ignore the second column for records other than first. But it is very rude and I do not recommend doing so.
Not sure if this is what you are asking for but you can call the ##Rowcount function to return the count of the previous select statement that has been executed.
SELECT mytable.mycol FROM mytable WHERE mytable.foo = 'bar'
SELECT ##Rowcount
If you want the row count included in your result set you can use the the OVER clause (MSDN)
SELECT mytable.mycol, count(*) OVER(PARTITION BY mytable.foo) AS 'Count' FROM mytable WHERE mytable.foo = 'bar'
You could also perhaps just separate two SQL statements with the a ; . This would return a result set of both statements executed.
You would used count(*)
SELECT count(distinct last)
FROM (XYZTable)
WHERE date(FROM_UNIXTIME(time)) >= '2013-10-28' AND
id = 90 ;

Querying a query

I've more experience using Access where I would build up my analysis in small parts and query each new view.
I'm not trying to do something that must be simple in SQL.
If I have a query of the format:
SELECT events.people, COUNT(events.eventType) AS usersAndEventCount
FROM theDB.events
WHERE event_id = 884
GROUP BY people
And I then want to query usersAndEventCount
like so:
Select usersAndEventCount.people, usersAndEventCount.events
FROM [from where actually?]
Tried from:
usersAndEventCount;
events
theDB.events
This must seem very basic to SQL users on SO. But in my mind it's much easier to breakdown the larger query into these sub queries.
How would I query usersAndEventCount in the same query?
Your statement "then want to query usersAndEventCount" does not make sense because usersAndEventCount is a column - at least in your first example. You can not "query" a column.
But from the example you have given it seems you want something like this:
Select usersAndEventCount.people, usersAndEventCount.events
FROM (
SELECT events.people,
COUNT(events.eventType) AS as events
FROM theDB.events
WHERE event_id = 884
GROUP BY people
) as usersAndEventCount
This is called a "derived table" in SQL
In pure SQL, you can use nested queries (AKA sub-queries). Just enclose your first query in () brackets, so your query will look like this:
Select usersAndEventCount.people, usersAndEventCount.events
FROM (SELECT events.people, COUNT(events.eventType) AS events
FROM theDB.events
WHERE event_id = 884
GROUP BY people) usersAndEventCount
Alternatively, to save the first query and reuse it in several places like you were doing in Access, you can save it as a View or Stored Procedure depending on the database system you're using. If you want an example, let me know the database system you're using.
I am not sure per 100%, because at the moment i can not test. But I think it should work.
uaec is the alias for the subquery. This alias you can use in the main query
Select uaec.people, uaec.usersAndEventCount
FROM (SELECT events.people, COUNT(events.eventType) AS usersAndEventCount
FROM theDB.events
WHERE event_id = 884
GROUP BY people) uaec

Distinct elements in django model

I'm a Django newbie and I wonder if there is a more efficient way (at a database level) of doing the following.
I have the model:
class Foo(models.Model):
item=models.IntegerField()
another_item=models.IntegerField()
And want to get an iterable of all the distinct values of "item".
This is what I have so far:
distinct=set([row.item for row in Foo.objects.all()])
This is easy to understand. But if I'm understanding how Django works then the SQL query is not very efficient because it is something like:
SELECT * FROM DB
when I only need:
SELECT DISTINCT item FROM DB
Any way of doing this more efficiently?
You want to use the distinct clause in combination with the values or values_list clauses.
Doc starts here. distinct, values and values_list are all in there.
So you could do:
Foo.objects.values_list('item', flat=True)
And that would return a list of item - matching your SELECT DISTINCT item FROM DB query.

Could you do a query with subqueries like this with nhibernate?

If you had a query that looks like this, could it be converted into a nhibernate query?
SELECT ....
FROM
(
SELECT ...
FROM ...
GROUP BY...
ORDER BY ...
UNION
SELECT ..
FROM ...
)
AS ASDF
GROUP BY ...
ORDER BY ...
With hibernate you can do native SQL queries. You just need to create a named Sql query mapping, and map it to a class.
However, you will not get the benefit of writing to the named query. [Which is to be expected]
if by "nhibernate query" you mean to use any non-sql method to express an sql query, like using HQL or the ICriteria api, no you wouldn't be able to use the union or to express a result set using select * FROM ( select ... ) as FOO
The named query that monksy refers to is writing an SQL-query that you bind to the mapping but you cannot manipulate that query in many ways

How to do a "null-table" select in NHibernate?

In other words how do you do something simple like this:
select 1
Or more specifically in the particular problem I'm dealing with, something like this:
SELECT (case when exists (<subquery>) then 1 else 0 end) AS result
So in short is there a way in NHibernate to do a select without having it generate the "FROM table" clause?
You are approaching this problem wrong.
Execute the subquery you are after using a count projection then do the if else logic in code.
I'd turn that <subquery> into a select top 1 id from table style query. Then check for a non-null result. Any NH query will always start from table.