I'm creating a simple query with aggregates. The example is:
string query = new SubSonic.Query.Select(
SubSonic.Query.Aggregate.GroupBy("ProductID", "ID"),
SubSonic.Query.Aggregate.Max("Price", "MaxPrice")
).From("Orders").ToString();
The Sql Result is:
SELECT ProductID AS ID, MAX(Price) AS MaxPrice
FROM [Orders]
when the result should be:
SELECT ProductID AS ID, MAX(Price) AS MaxPrice
FROM [Orders]
GROUP BY ProductID
In SubSonic2.2 the result is correct but in Subsonic3, the GROUP BY statement dissapears and the query return only one row.
Is my SqlQuery expression correct or is it a bug in SubSonic3?
Not entirely sure about the exact syntax, I use the
MyTableClass.All().Max
Notation for querying it.Your example looks wrong though, because your groupBy is inside your select. The groupBy is not part of the select, so maybe you need to move that GroupBy outside your select
Related
I'm trying to do the following sql query with linq but I couldn't understand it and it sounds confused.
Can I do it with linq or lambda?Can you help me write this query with linq?
int pp=0;
int typesquery=0;
string query;
if
{
a is change value.
}
I try:
SELECT TOP PERCENT NAME,SURNAME,DEPARTMENTID,DEPARTMENTNAME,ROW_NUMBER() over(PARTITION BY
NAME,SURNAME ORDER BY NAME,SURNAME) AS INF_NUMBER
FROM PERSON AS S
GROUP BY NAME,SURNAME,PERSONNUM,DEPARTMENTID,DEPARTMENTTYPE
THİS Linq query
var query= from x in PERSON
.OrderBy( x => x.NAME, x=>x.SURNAME)
.SELECT (x=>x.NAME,x=>x.SURNAME,x=>x.DEPARTMENTID,x=>x.DEPARTMENTNAME)
but not Couldn't combine batch way.
In LINQ, I am trying to inner join custom function written for full-text search and an Iqueryable result.
However, I get the following error when I try to to_ret.select(--something--).ToList()
Nested query does not have appropriate key
LINQ Code:
var sql_query = db.search(st);
var to_ret = from ts in sql_query
from t in table
where t.Id == ts.Value select t;
to_ret = to_ret.Include(x => x.table1)
.Include(x=> x.table2.Select(y=> y.table2Col));
to_ret.select(-something-).toList();
SQL Code:
create function [dbo].[search]
(#keywords nvarchar(4000))
returns table
as
return (
select [key] from containstable(tb,(Name,Description),#keywords)
)
Code that works in place of above LINQ Code :
var ids = (from t in table join ts in db.search(st) on t.Id equals ts.Value select t.Id).ToList();
to_ret = to_ret.Where(x => ids.Contains(x.Id));
However, the code that works isn't efficient enough as it eagerly loads all the ids for comparison
Do not join the table using LINQ, it is not effective.
You need to include all the joined functions into [dbo].[search] table valued function (like a view). Then do just call the [dbo].[search] from EF and filter it.
I have mentioned joined Fulltext table valued function here.
Note that fulltext and filtering together in one query could take time, because it is not easy job for query optimizer. Query optimizer selects to perform first fulltext on entire table(s) and then filtering or the opposite way.
Is there any way to write a linq query to result in :
select Count(Id) from tbl1
because
tbl1.Select(q=>q.Id).Count()
doesn't translate to the result that I want
update :
it returns :
select count(*) from tbl1
Update after answer :
I tested the scenario with more than 21,000,000
Is there any way to write a linq query to result in.
No. First thing is to understad what you need, for sample, in T-SQL, you can use:
COUNT(*) will counts the rows in your table
COUNT(column) will counts the entries in a column - ignoring null values.
If you need to count how many rows you have, just use
var total = tbl1.Count();
If you need to see how many entities you have where a specific column is not null, then use a filter overloads of Count method.
var total = tbl1.Count(x => x.Id != null);
No, it is not possible. There is not difference realted with performance using Count(*) or ´Count(Id), even more if yourId` is the primary key.
I did an experiment with a table here with more than one million tuples. See the executioon plan of both queries. The first one is the select count(*) and second one is select count(id). The id is the primary key (sorry the results are in portuguese-brazil):
Using count(field) in sql counts all non-null values. In linq, you can say:
tbl1.Where(q => q.Id != null).Count();
or simply:
tbl1.Count(q => q.Id != null);
A possibility to get
select Count(Id) from tbl1
would be
tbl1.Where(q => q.Id != null).Select(x => x.Id).Distinct().Count();
The above Where is there to avoid null values. If you want them to also be counted, the Where needs to be eliminated and the Select adjusted to deal with null entries.
Additionally if you don't want to count just distinct values then the Select and Distinct parts can be disregarded.
I have two Tables - tblExpenses and tblCategories as follows
tblExpenses
ID (PK),
Place,
DateSpent,
CategoryID (FK)
tblCategory
ID (PK),
Name
I tried various LINQ approaches to get all distinct records from the above two tables but not with much success. I tried using UNION and DISTINCT but it didnt work.
The above two tables are defined in my Model section of my project which in turn will create tables in SQLite. I need to retrieve all the distinct records from both the tables to display values in gridview.
Kindly provide me some inputs to accomplish this task. I did some research to find answer to this question but nothing seemed close to what I wanted. Excuse me if I duplicated this question.
Here is the UNION, DISTINCT approaches I tried:
DISTINCT # ==> Gives me Repetitive values
(from exp in db.Table<tblExpenses >()
from cat in db.Table<tblCategory>()
select new { exp.Id, exp.CategoryId, exp.DateSpent, exp.Expense, exp.Place, cat.Name }).Distinct();
UNION # ==> Got an error while using UNION
I think union already does the distict when you join the two tables you can try somethin like
var query=(from c in db.tblExpenses select c).Concat(from c in
db.tblCategory select c).Distinct().ToList();
You will always get DISTINCT records, since you are selecting the tblExpenses.ID too. (Unless there are multiple categories with the same ID. But that of course would be really, really bad design.)
Remember, when making a JOIN in LINQ, both field names and data types should be the same. Is the field tblExpenses.CategoryID a nullable field?
If so, try this JOIN:
db.Table<tblExpenses>()
.Join(db.Table<tblCategory>(),
exp => new { exp.CategoryId },
cat => new { CategoryId = (int?)cat.ID },
(exp, cat) => new {
exp.Id,
exp.CategoryId,
exp.DateSpent,
exp.Expense,
exp.Place,
cat.Name
})
.Select(j => new {
j.Id,
j.CategoryId,
j.DateSpent,
j.Expense,
j.Place,
j.Name
});
You can try this queries:
A SELECT DISTINCT query like this:
SELECT DISTINCT Name FROM tblCategory INNER JOIN tblExpenses ON tblCategory.categoryID = tblExpenses.categoryID;
limits the results to unique values in the output field. The query results are not updateable.
or
A SELECT DISTINCTROW query like this:
SELECT DISTINCTROW Name FROM tblCategory INNER JOIN tblExpenses ON tblCategory.categoryID = tblExpenses.categoryID;<br/><br/>
looks at the entire underlying tables, not just the output fields, to find unique rows.
reference:http://www.fmsinc.com/microsoftaccess/query/distinct_vs_distinctrow/unique_values_records.asp
I have this hql query, which works perfect:
select m
from Media m
join m.Productlines p
join m.Categories c
join m.Spaces sp
join m.Solutions so
where m.Uid != 0
and p.Uid in (:productlines)
and c.Uid in (13)
and sp.Uid in (52)
and so.Uid in (15,18)
group by m.Uid
But now it needs to be parameterized/made dynamic, not only the parameters, but also the joins (it is possible to select only from Media, without any joins, and so no *.Uid in will be required in this case).
I dont want to mess around with a StringBuilder instance and build the hql query that way, I would rather like to use the Criteria API, but I cant get a
SELECT m.*
....
GROUP BY m.Uid
query to work with Criteria.
If I add a
Projections.GroupProperty("Uid")
to my query, nhibernate selects
SELECT m.Uid
....
GROUP BY m.Uid
which is of course wrong.
After that, I also need to count the unique rows the query returned, as the result is paged.
So, my other query is quite similiar, but I cant find a Criteria equivalent for
SELECT COUNT(DISTINCT m.Uid)
Here is the HQL:
select count(distinct m.Uid)
from Media m
join m.Productlines p
join m.Categories c
join m.Spaces sp
join m.Solutions so
where m.Uid != 0
and p.Uid in (:productlines)
and c.Uid in (13)
and sp.Uid in (52)
and so.Uid in (15,18)
How can this be done with Criteria API?
Please, (N)Hibernate experts - help me with this, I cant find a working solution. Any help is greatly appreciated!
Group columns are implicitly returned as result, but you can add more columns. AFAIK, you can return full entities:
var query = session.CreateCriteria(typeof(Media), "m")
.Add(Projections.GroupProperty("m"))
.Add(Restrictions.NotEq("m.Uid", 0));
// dynamically add filters
if (filterProductLines)
{
query
.CreateCriteria("m.Productlines", "p")
.Add(Restrictions.Eq("p.Uid", productLines));
}
// more dynamic filters of this kind follow here...
IList<Media> results = query.List<Media>();
To count the full number of results you can just build up the same query with different projection:
var query = session.CreateCriteria(typeof(Media), "m")
.SetProjection(Projections.CountDistinct("m.Uid"));
// rest of the query the same way as above
long totalNumberOfResults = query.UniqueResult<long>();
I'm getting unsure about the Projections.GroupProperty("m"), you need to try this. If it doesn't work, you could make it an DetachedQuery that only returns ids:
var subquery = DetachedCriteria.For(typeof(Media), "m")
.Add(Projections.GroupProperty("m.Uid"))
.Add(Restrictions.NotEq("m.Uid", 0));
// add filtering
var query = session.CreateCriteria(typeof(Media), "outer")
.Add(Subqueries.PropertyIn("outer.Uid", subquery));
IList<Media> results = query.List<Media>();
This creates a sql query like this:
select outer.* // all properties of Media to create an instance
from Media outer
where outer.Uid in (
select Uid
from media m
where // filter
)
var count = session.CreateCriteria(typeof(Media))
// Add other criterias...
.SetProjection(Projections.CountDistinct("Id")) // or whatever the id property of Media class is called
.UniqueResult<long>();
As to your GROUP BY question, the query:
SELECT m.*
....
GROUP BY m.Uid
makes no sense because you need to select only columns that appear in the group by clause or aggregate functions. Could you elaborate a little more as to what exactly are you trying to achieve?