How to get rows by LINQ - linq

Everybody.
I have following data.
DATE|COLUMN1|COLUMN2|VALUE
--------------------------
1 |A |D |100
--------------------------
2 |A |D |200
--------------------------
1 |B |D |150
I need get rows where DATE does have max value. Like that
DATE|COLUMN1|COLUMN2|VALUE
--------------------------
2 |A |D |50
--------------------------
1 |B |D |150
Sorry for my bad English.

As I can understand, you need max date for every group of column1 -
for that you can go with
var custsLastAccess = from c in db.data //data is your table
group c by c.COLUMN1 into grp
select grp.OrderByDescending(c => c.DATE).FirstOrDefault();

You can first select the max from the LINQ and then select by this max:
var max = rows.Max(a => a.DATE);
var result = rows.Where(a => a.DATE == max).ToList();
Simplier:
var result = rows.Where(a => a.DATE == rows.Max(b => b.DATE)).ToList();
Optimizer/compiler should optimize the query above.
Expression:
var result = from r in rows
where r.DATE == rows.Max(a => a.DATE)
select r;

I found solve. The following code decided mine task.
public override IQueryable<ENTITY> Get()
{
return base.Get().GroupBy(x => new { x.COLUMN1, x.COLUMN2 }, (key, group) => new
{
row = group.OrderByDescending(x => x.DATE).FirstOrDefault()
}).Select(x => x.row);
}

Related

Can not join tables with LINQ

I will glad if you help me
I have 4 tables:
http://i.stack.imgur.com/MMIdn.png
I need to get a ApptNumber from Condo and ContractID from Contract
If no contracts assigned to the condo, leave it blank.
Like this:
| Cnds | Cntrcts |
|--------|-----------|
| 101 | contr1 |
| 102 | contr2 |
| 103 | contr3 |
| 104 | |
| 105 | |
| 106 | contr4 |
| 107 | |
|--------|-----------|
I tried to do it like this, but failed to get the right result
var q =
from c in condos
join b in buildings on c.buildingID equals b.BuildingId
join t in tenants on b.BuildingId equals t.buildingID
join ct in contracts on t.TenantID equals ct.tenantID into result
from subresult in result.DefaultIfEmpty()
select new
{
c.apptNumber,
contract = (subresult == null ? 0 : subresult.ContractID)
};
Sincerely
from c in context.Condos
join ct in context.Contracts on c.apptNumber equals ct.SuiteNo into j
//it could be another field for joining
from d in j.DefaultIfEmpty()
select new {c.apptNumber, Contract = d != null ? d.ContractId : null}
Thank you guys. It was my fault to use multiple JOINS in first place.
I resolved the issue like that:
var q =
from c in condos
join ct in contracts on c.apptNumber equals ct.SuiteNo into j //it could be another field
from d in j.DefaultIfEmpty()
select new { c.apptNumber, Contract = d != null ? d.ContractID : 0 };
var q2 = q.GroupBy(c => c.apptNumber).Select(group => group.First());

Select list value based on second column

I have 2 column list value
ptext | stylename
-----------|------------
aaa | styleone
ccc | styleone
ddd | styleone
fff | styletwo
ggg | styletwo
xyx | styleone
dkk | styleone
I would like to have List like this
ptext | stylename
----------------|------------
aaa,ccc,ddd | styleone
fff,ggg | styletwo
xyx,dkk | styleone
please help using some linq query
Group items by stylename property, then project each group ptext values into string joined with coma
list.GroupBy(x => x.stylename)
.Select(g => new {
stylename = g.Key,
ptext = String.Join(",", g.Select(x => x.ptext))
});
Or with query syntax:
from x in list
group x by x.stylename into g
select new { // or new YourItemType {
stylename = g.Key,
ptext = String.Join(",", g.Select(x => x.ptext))
}
You can of course create objects of your list items type instead of anonymous objects.

Select nested list

I have three tables in DB like this:
products
+----+------+
| id | name |
+----+------+
| 1 | prod1|
+----+------+
values
+----+---------+---------+
| id | value | alias |
+----+---------+---------+
| 1 | 10 g | 10m |
+----+---------+---------+
prdoucts_values
+---------------+---------+
| product_id | value_id|
+---------------+---------+
| 1 | 1 |
+---------------+---------+
How select all products from DB, that have any value from List<Values.alias> ?
List<decimal> aliases = ...
var query = db.Products.Where(p => p.Values.Any(v => aliases.Contains(v.Alias)));
Or (if you don't have navigation properties)
var query = from p in db.Products
join pv in db.ProductsValues on p.ProductId equals v.ProductId
join v in db.Values on pv.ValueId equals v.ValueId into values
where values.Any(v => aliases.Contains(v.Alias))
select p
If you are using EF (database first) then the table prdoucts_values is not part of the conseptual model.
instead EF givs you a direct path from Products to Values
Therefore you can write a query that look like this:
var lst = new List<Products>();
lst = db.Products.Where(c => c.Values.Any()).ToList();

Pivoting in Linq [duplicate]

This question already has answers here:
Pivot data using LINQ
(5 answers)
Closed 9 years ago.
I am using LINQ-to-Entities, and would like to perform a pivot.
For exampe, I have this table:
| data1 | data2 |
+-------+-------+
| 1 | A |
| 1 | B |
| 2 | P |
| 2 | Q |
| 2 | R |
+---------------+
And I want to pivot it into the following results:
| data1 | first | second | third |
+-------+-------+--------+-------+
| 1 | A | B | NULL |
| 2 | P | Q | R |
+--------------------------------+
I would like to do this in LINQ, without needing to do client-side processing.
I have seen these SO posts, but they do not quite address the above situation (as far as I can tell).
Pivot data using LINQ
Is it possible to Pivot data using LINQ?
Note
I have tried the below, but it complains that I cannot use Skip() on an unordered collection, and I don't see a way to get the group's collapsed 'data2' info sorted.
from item in MyTable
group item by item.data1 into g
select new
{
data1 = g.Key,
first = g.Skip(0).FirstOrDefault().data2,
second = g.Skip(1).FirstOrDefault().data2,
third = g.Skip(2).FirstOrDefault().data2,
};
I assume that you could have more than three columns from the data2 field?
If so there's no way to do you query that returns an anonymous type with a variable number of properties. You need to return an array or some sort of list for the data2 set of values.
I think this is the kind of thing that you can do:
var query =
from mt in MyTable
group mt.data2 by mt.data1 into gmts
let d2 = gmts.ToArray()
select new
{
data1 = gmts.Key,
data2 = d2,
length = d2.Length,
};
var pending = query.ToArray();
var maxLength = pending.Max(p => p.length);
Func<string[], string[]> extend = xs =>
{
var r = new string[maxLength];
xs.CopyTo(r, 0);
return r;
};
var results =
from p in pending
select new
{
p.data1,
data2 = extend(p.data2),
};
This produces a series of anonymous type with the data2 array all being the same size to fit the maximum number of results for any of the data1 fields.
The query is still executed as a single SQL query. And the in-memory processing is fast.
Does this work for you?
EDIT
Since you know you have a fixed number of columns (as per comment) you can easily change my results query to meet your requirements:
var results =
from p in pending
let d2s = extend(p.data2)
select new
{
p.data1,
first = d2s[0],
second = d2s[1],
third = d2s[2],
};
Hmm, this seems to work, though I wonder how efficient it is.
from item in MyTable
group item by item.data1 into g
select new
{
data1 = g.Key,
first = g.OrderBy(x => x.data2).Skip(0).FirstOrDefault().data2,
second = g.OrderBy(x => x.data2).Skip(1).FirstOrDefault().data2,
third = g.OrderBy(x => x.data2).Skip(2).FirstOrDefault().data2,
};
The corresponding SQL generated (from LINQPad) is:
SELECT [t1].[data1], (
SELECT [t5].[data2]
FROM (
SELECT TOP (1) [t4].[data2]
FROM (
SELECT [t3].[data2], [t3].[ROW_NUMBER]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [t2].[data2]) AS [ROW_NUMBER], [t2].[data2]
FROM [MyTable] AS [t2]
WHERE [t1].[data1] = [t2].[data1]
) AS [t3]
WHERE [t3].[ROW_NUMBER] > #p0
) AS [t4]
ORDER BY [t4].[ROW_NUMBER]
) AS [t5]
) AS [first], (
SELECT [t10].[data2]
FROM (
SELECT TOP (1) [t9].[data2]
FROM (
SELECT [t8].[data2], [t8].[ROW_NUMBER]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [t7].[data2]) AS [ROW_NUMBER], [t7].[data2]
FROM (
SELECT [t6].[data2]
FROM [MyTable] AS [t6]
WHERE [t1].[data1] = [t6].[data1]
) AS [t7]
) AS [t8]
WHERE [t8].[ROW_NUMBER] > #p1
) AS [t9]
ORDER BY [t9].[ROW_NUMBER]
) AS [t10]
) AS [second], (
SELECT [t15].[data2]
FROM (
SELECT TOP (1) [t14].[data2]
FROM (
SELECT [t13].[data2], [t13].[ROW_NUMBER]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [t12].[data2]) AS [ROW_NUMBER], [t12].[data2]
FROM (
SELECT [t11].[data2]
FROM [MyTable] AS [t11]
WHERE [t1].[data1] = [t11].[data1]
) AS [t12]
) AS [t13]
WHERE [t13].[ROW_NUMBER] > #p2
) AS [t14]
ORDER BY [t14].[ROW_NUMBER]
) AS [t15]
) AS [third]
FROM (
SELECT [t0].[data1]
FROM [MyTable] AS [t0]
GROUP BY [t0].[data1]
) AS [t1]

How to make null equal null in oracle

I have a variable being passed to my stored proc and it's a filter (basically). However, that field can sometimes be null, and if it is, I want to be able to check against the rows that have that field as null.
For example,
Table A:
VALUE_COLUMN | FILTER_COLUMN
----------------------------
A | (NULL)
B | (NULL)
C | (NULL)
D | (NULL)
A | 1
E | (NULL)
F | (NULL)
B | 1
The query (With inputs, val, filter):
SELECT COUNT(1)
FROM TableA
WHERE
wrap_up_cd = val
AND brn_brand_id = filter
Expected I/O:
val = A, filter = (null) = 1
val = A, filter = 1 = 1
val = C, filter = 1 = 0
How can I make Oracle behave this way?
How about:
SELECT COUNT(1)
FROM TableA
WHERE
wrap_up_cd = val
AND ((brn_brand_id = filter) OR (brn_brand_id IS NULL AND filter IS NULL))
I'm not an Oracle expert, but I'd expect that to work - basically make the query match if both the filter and the value are NULL.
Oracle doesn't have an ISNULL function. So you'd need something like
SELECT COUNT(*)
FROM tableA
WHERE brn_brand_id = filter
OR ( brn_brand_id IS NULL
AND filter IS NULL)
This can also be handy at times:
SELECT COUNT(*)
FROM tableA
WHERE
NVL(brn_brand_id, CHR(0)) = NVL(filter, CHR(0))

Resources