There are examples with group by - having count or select minimum date with linq on the web but I couldn't find a particular solution for my question. And also I don't have an advanced linq understanding to combine these solutions that I found so far.
I have a SQL query like this:
select client_id
from my_table /* Column1 : client_id, Column2 : _month */
group by client_id
having min(_month) = '2009-11'
My question is: How can I convert this query into c# linq?.
So far I wrote something like this but it doesn't give what I have to have:
var query = dataTable.AsEnumerable() // This is my_table
.GroupBy(c => c.Field<Int32>("client_id"))
.Select(g => new
{
g.Key,
minMonth = g.Min(c => c.Field<string>("_month"))
})
.Where(d => d.minMonth == "Some String like '2009-11'");
It actually gives me the result of this SQL which I don't need:
select client_id, min(_month)
from my_table
where _month = '2009-11'
group by client_id
Note: _month is a string which is formatted like YYYY-MM.
Try this:
var results = mytable.GroupBy(x => x.client_id)
.Where(x => x.Min(y => DateTime.ParseExact(y._month,"yyyy-MM",null))
== new DateTime(2009,11,1))
.Select(x=>x.Key);
The having clause is implemented within the Where in this LINQ statement. After grouping by client_id, we use x.Min to implement the min aggregate function on _month, and then use the ParseExact method to parse as a year-month combination to do the comparison.
From the SQLFiddle provided by OP, there are 4 records returned. A demo using identical data and the above query also returns the same 4 records.
Related
I need to write the following SQL Server query in Entity Framework but have been unsuccessful so far. Can someone please help with converting to Entity Framework syntax?
SQL table
username, date, value
--------------------------
brad, 1/2/2010, 1.1
fred, 1/3/2010, 1.0
bob, 8/4/2009, 1.5
brad, 2/2/2010, 1.2
fred, 12/2/2009, 1.3
SQL Server Query
select t.username, t.date, t.value
from MyTable t
inner join (
select username, max(date) as MaxDate
from MyTable
group by username
) tm on t.username = tm.username and t.date = tm.MaxDate
The original question is here: https://stackoverflow.com/a/2411703/1355975
Assuming your database base class is DatabaseContext and you have a table named MyTable, you can select records from it this way:
using (var context = new DatabaseContext())
{
var myTableRecords = context.MyTable.SqlQuery("your query goes in here").ToList();
}
You can run any RAW SQL this way.
I think this is what I'm looking for - I'll need to tailor it slightly but should provide me with what I need:
DateTime utcDate = DateTime.UtcNow;
var result =
entries // e.g. context.tableName
.GroupBy(e => e.username)
.Select(gr =>
gr
.Where(x => x.date < utcDate)
.OrderByDescending(x => x.date)
.FirstOrDefault()) // This will give us null for devices that
// don't have a status entry before the date
.AsEnumerable()
.ToList();
https://stackoverflow.com/a/37757982/1355975
I have a query I know how to do in SQL but struggling to figure out the LINQ query. Here is the SQL.
SELECT ordNo, tranNo, COUNT(distinct custNo)
FROM orders
GROUP BY ordNo, tranNo
HAVING COUNT(distinct custNo) > 1
I don't feel like this is the same question that I see you marked as a duplicate. The linked question only groups on a single property. I've lost track of the Linq queries I've tried but here is one.
var countList = from o in orders
group o by new {o.orderNo, o.tranNo, o.custNo}
into grp
where grp.Key.custNo.Distinct().Count() > 1
select grp;
I tried the suggestion below but like someone commented you can't access the custNo property.
Just spitballing since I don't know the table structure.
context.orders
.GroupBy(o => new { o.ordNo, o.tranNo, o.custNo })
.Where(o => o.custNo.Distinct().Count() > 1)
.Select(o => new {
ordNo = o.ordNo,
tranNo = o.tranNo
});
I have the next query:
select VisitLines.ProcedureId, COUNT(DISTINCT VisitLines.VisitId) as nt
from Visits
LEFT JOIN VisitLines ON Visits.Id = VisitLines.VisitId
WHERE Visits.VisitStatusId = 1 AND Visits.IsActive = 1 AND VisitLines.IsActive = 1
GROUP BY VisitLines.ProcedureId
Main question: Does ability exists to grouping by column from join using linq ? I'm wondering how to do it using 'collection' column.
Is it possible to force EF to generate COUNT(DISTINCT column) ? IQueryable.GroupBy.Select(x => x.Select(n => n.Number).Distinct().Count()) generate query with few subqueries which much slower then COUNT(DISTINCT )
I found. Need to use SelectMany with second parameter resultSelector:
dbContext.Visits.Where(x => x.IsActive)
.SelectMany(x => x.VisitLines, (v, vl) => new
{
v.Id,
vl.ProcedureId
})
.GroupBy(x => x.ProcedureId)
.Select(x => new
{
Id = x.Key,
VisitCount = x.Count()
}).ToArray();
It generates the desired SQL, but with exception that I need distinct count by visit.
And if I change VisitCount = x.Distinct().Count() then EF generates a query with few subqueries again. But the main issue resolved
I have a Linq Query that works well but I need to write the SQL Query
Can Anybody help me write it?
this query will search the database foreach a.h and a.HV in the view with the filters of time and model and in the end it checks the option Filter.M that if it is selected it will search for all the data selected in this DropDownCheckBoxes`
How can i write the this where and select part in SQL command?
ret1 = (from a in View
where
a.LastRefreshTime>=Filter.From && a.LastRefreshTime<=Filter.To && a.ModelCode == mdlCode &&
Filter.PN.Select(epn => epn.Substring(0, 11)).Contains(a.H) &&
Filter.PN.Select(epn => epn.Substring(14, 2)).Contains(a.HV)
select new RData
{
v = a.v,
Date = a.LastRefreshTime,
UserId = a.UserId,
M = a.Name,
}).Distinct().AsQueryable();
ret = ret1.Where(nr =>
Filter.M == null || !Filter.M.Any() || Filter.M.Contains(nr.M)
).ToList();
Here's a start for you
select a.v v,
a.LastRefreshTime "Date",
a.UserId,
a.Name
from a
where a.LastRefreshTime>= arg_filter_from
and a.LastRefreshTime<= arg_filter_to
and a.ModelCode = arg_mdlCode
.
.
.
In this query you'll need to replace 'arg_...' with the appropriate values or arguments you want.
Contains is roughly equivalent to "IN" in SQL. For example:
where a.Name in ('jim', 'bob', 'joe')
In can also be used with a subselect which is roughly what I think Filter.PN.Select is doing though I'm not a linq expert. Example:
where a.H in (Select foo from PN_Table)
Or simpler example continuing on the my previous name example:
where a.Name in (select first_name from table)
If we supposed that the Filter.PN list represent a table FilterPN in your sql database, that will be your converted code for the first linq query
select distinct a.v, a.LastRefreshTime, a.UserId, a.Name
from [view] a
where a.LastRefreshTime>= 'Filter.From' and
a.LastRefreshTime<='Filter.To' and a.ModelCode = 'mdlCode' and
exists(select top 1 * from FilterPN where Substring(epn, 1, 11) = a.H) and
exists(select top 1 * from FilterPN where Substring(eenter code herepn, 15, 2) = a.HV)
think to replace the enquoted variables with ur real values 'Filter.To'...
I am trying to convert the following MySql to Linq to Sql (with or without Lambda experessions)
select * from table where table.column2 < '2014-11-27 00:00:00' group by table.column1 having sum(table.column3 = 0) > sum(table.column3 = 1)
Is it possible and if so any pointers?
Column1 is a string,
Column2 is a DateTime,
Column3 is a TinyInt (Boolean)
IQueryable<MyType> query = // get table IQueryable from the Linq2Sql data context
var dateTime = DateTime.Parse("2014-11-27");
var result = query.Where(t => t.Column2 < dateTime)
.GroupBy(t => t.Column1)
// Linq doesn't have HAVING, you can just use Where(). Here, we're operating on
// an IQueryable of IGrouping, and we're filtering based on taking sums over the groups
.Where(g => g.Sum(t => !t.Column3 ? 1 : 0) > g.Sum(t => t.Column3 ? 1 : 0))
// it's not clear to me what you want here. Without any Select, each full grouping will get
// pulled into memory as an IGrouping. If instead you just want the Column1 values, you'd
// want .Select(g => g.Key)
.Select(...);
Note I'm assuming here that you've mapped Column3 to a bool in your entity classes. If you instead have it as a byte, then you'll have to do t.Column3 == 0 instead of !t.Column3.