Linq group by + where for each group - linq

I want to write a linq expression that will return the ID that does not contain a particular value. For example, I want to return all distinct IDs that do not have Value = 30.
ID, Value
1, 10
1, 20
1, 30
2, 10
2, 20
3, 10
3, 20
The result should be 2 and 3 since non of these have a Value with 30.
Is this possible to do with a single expression?
Thanks

Sure, this will do it:
var query = from i in list
group i by i.GroupId into g
where g.Any(p => p.ItemId == 30) == false
select g.Key;
foreach(var result in query) { Console.WriteLine(result); }
This outputs:
2
3
Here I have used, as an example:
class Product {
public int GroupId { get; set; }
public int ItemId { get; set; }
}
and
var list = new List<Product>() {
new Product() {GroupId = 1, ItemId = 10},
new Product() {GroupId = 1, ItemId = 20},
new Product() {GroupId = 1, ItemId = 30},
new Product() {GroupId = 2, ItemId = 10},
new Product() {GroupId = 2, ItemId = 20},
new Product() {GroupId = 3, ItemId = 10},
new Product() {GroupId = 3, ItemId = 20},
};

I don't have Linq, but here is the SQL Server SQL to do what you want:
DECLARE #YourTable table (ID int, value int)
insert into #YourTable VALUES (1, 10)
insert into #YourTable VALUES (1, 20)
insert into #YourTable VALUES (1, 30)
insert into #YourTable VALUES (2, 10)
insert into #YourTable VALUES (2, 20)
insert into #YourTable VALUES (3, 10)
insert into #YourTable VALUES (3, 20)
SELECT DISTINCT ID
FROM #YourTable y1
WHERE NOT EXISTS (SELECT Value
FROM #YourTable y2
WHERE y1.ID=y2.id and y2.value=30)
OUTPUT:
ID
-----------
2
3
(2 row(s) affected)

Related

HBase FuzzyRowFilter doesn't work

I have a row key composed of twenty characters like this:
XXAAAAXXXXXXXXXXXXXXX
I want to scan using a FuzzyRowFilter on the AA value on 2 to 6 position . But AA is not fixed value.
If you don't have AAAA as fixed,you can do like this :
FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ONE);
String[] matches=new String[]{"AAAA","BBBB"};
for (String match:matches) {
byte[] rk = Bytes.toBytesBinary("??" + match + "??????????????");
byte[] fuzzyVal = new byte[]{1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
List<Pair<byte[], byte[]>> pairs = new ArrayList<>();
pairs.add(new Pair<>(rk, fuzzyVal));
filterList.addFilter(new FuzzyRowFilter(pairs));
}
Scan scan=new Scan();
scan.setFilter(filterList);
This will filter based on all the fuzzyFilters in the list and match based on FilterList.Operator.MUST_PASS_ONE.
Based on your requirements,go ahead and modify it accordingly.
Sorry but using,
FilterList filterList = new FilterList(/*FilterList.Operator.MUST_PASS_ONE*/);
String[] matches=new String[]{"1609","1610"};
for (String match:matches) {
byte[] rk = Bytes.toBytesBinary("??" + match + "??????????????");
byte[] fuzzyVal = new byte[]{1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
List<Pair<byte[], byte[]>> pairs = new ArrayList<>();
pairs.add(new Pair<>(rk, fuzzyVal));
filterList.addFilter(new FuzzyRowFilter(pairs));
}
Scan scan_fuzzy=new Scan();
scan_fuzzy.setFilter(filterList);
ResultScanner rs_fuzzy = table.getScanner(scan);
for( Result result : rs_fuzzy) {
System.out.println(result);
System.out.println("Value: " + Bytes.toString(result.getValue(FAMILY,COLUMN)));
}
my result doesn't contain just the row corresponding to the rowkey :02160901222720647002
but all the row (and the rowkey) of my table

Hide all months except current

I have a sheet with columns for each month. Column C is January (cell C1 = 1), Column D is February (cell D1 = 2), etc.
I'm trying to hide all of the month columns except the current month. I think I'm getting close but the logic escapes me.
Suggestions?...JD
function HideTheMonths(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Sum Remaining");
var date = new Date();
var mo1 = date.getMonth();
var mons = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
var curmons = mons[mo1];
for (var x = 3; x < 15; x++){
var c = s.getRange(1, x)
if (curmons = c) {
var datarange = s.hideColumns(x);
}
}
}

How can I bind group by query to DataGridview in linq?

I want bind the below query to DataGridview.
how can I it?
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
var numberGroups =
from num in numbers
group num by num % 5 into numGroup
select new { Remainder = numGroup.Key, Numbers = numGroup };
How do you want it represented in the DGV since Numbers could contain more than one item how would this go into a DGV row?
Alternatively this should work:
var numberGroups = from num in numbers
group num by num % 5 into numGroup
select new { Remainder = numGroup.Key, Count = numGroup.Count() };
yourGridView.DataSource = numberGroups.ToList();
yourGridView.DataBind(); //don't use if WinForm DGV

Linq: Select 1st item from other group

I am trying to write a query to find just one item from the group, where they grouped by Industry and Weight, then from this one I have to get where Weight is Max and Balance is Max too
This is the example:
var data = new[] {
new {ID = 1, Industry = 2, Weight = 2, Balance = 500},
new {ID = 2, Industry = 2, Weight = 2, Balance = 300},
new {ID = 3, Industry = 2, Weight = 1, Balance = 100},
new {ID = 5, Industry = 4, Weight = 1, Balance = 100},
new {ID = 6, Industry = 4, Weight = 2, Balance = 150},
new {ID = 7, Industry = 4, Weight = 1, Balance = 300},
};
var res = from a in data group a by new {a.Industry, a.Weight} into g
let ID = g.First().ID
let Balance = g.Max(a => a.Balance)
select new { ID, g.Key.Industry, g.Key.Weight, Balance};
Console.WriteLine(res);
So as the result I should get just two records
ID Industry Weight Balance
1 2 2 500
6 4 2 150
but with query above I got 4 records
Any advice?
Regards,
Dmitriy
There are probably many different solutions, but one would be to only group by Industry and sort each group according to your "first element to pick" criteria and then pick the first item in each group.
var res = from item in data
group item by item.Industry into g
let first = g.OrderByDescending(x => x.Weight)
.ThenByDescending(x => x.Balance).First()
select first;
data.GroupBy(x=>new {x.Industry,x.Weight})
.ToDictionary(y=>y.Key,y=>y.ToList().Max(x=>x.Balance));
If you dont want a dictionary then you can as well Select a new DTO or a dynamic object as follows:
data.GroupBy(x=>new {x.Industry,x.Weight})
.Select(x=>new {x.Key.Industry,x.Key.Weight,x.ToList().Max(y=>y.Balance)});
Hopefully that is what you need.

Dynamic linq - Group by interval (DateTime, Numeric)

I search everywhere and didn`t find anwser for this question. I want to group by intervals (DateTime, Numeric) in Dynamic linq (the data will be crated dynamically so i must use dynamic linq)
Lets assume that we have such data:
ID|Date|Price
1|2010-11-01|100
2|2010-11-01|120
3|2010-11-02|50
4|2010-12-01|30
5|2010-12-01|220
6|2011-01-01|400
How to get this data grouped by like this
-(Group by Day) following groups
->2010-11-01 = 2 elements
->2010-11-02 = 1 elements
->2010-12-01 = 2 elements
->2011-01-01 = 1 elements
-(Group by Month) following groups
->2010-11 = 3 elements
->2010-12 = 2 elements
->2011-01 = 1 elements
-(Group by Quarter) following groups
->2010 q.03 = 5 elements
->2011 q.01 = 1 elements
-(Group by Year) following groups
->2010 = 5 elements
->2011 = 1 element
-(Group by Price (From 0, Each 50)) following groups
-> <0-50) = 1 elements
-> <50-100) = 1 elements
-> <100-150) = 2 elements
-> <200-250) = 1 elements
-> <400-450) = 1 elements
-(ideally it would be Group by Price (From 0-50,From 50-150, From 150-500)) following groups
-> <0-50) = 1 elements
-> <50-150) = 3 elements
-> <150-500) = 2 elements
Any Ideas? I stress again - it must be DYNAMIC LINQ or eventually some sophisticated lambda expression? I should been able to "group" it by column name that will be in string. e.g.
GroupBy("Date"), GroupBy("Price");
Here's how to do it:
For instance:
Group by Month
public Item[] data =
{
new Item { Date = new DateTime(2011, 11, 6), Price = 103, Name = "a" },
new Item { Date = new DateTime(2011, 11, 16), Price = 110, Name = "b" },
new Item { Date = new DateTime(2011, 12, 4), Price = 200, Name = "c" },
new Item { Date = new DateTime(2011, 12, 4), Price = 230, Name = "d" },
new Item { Date = new DateTime(2012, 1, 15), Price = 117, Name = "e" }
};
var groups = data.AsQueryable().GroupBy("Date.Month", "it").Cast<IGrouping<int, Item>>();
You can use "Date.Day" and "Date.Year" and for something like a price range you could use a function which maps everything in the range onto the same value e.g. using integer division "(it.Price / 50)"

Resources