how to convert sql union to linq
Asked Answered
B

5

33

I have the following Transact SQL query using a union. I need some pointers as to how this would look in LINQ i.e some examples wouldbe nice or if anyone can recommend a good tutorial on UNIONS in linq.

select top 10 Barcode, sum(ItemDiscountUnion.AmountTaken) from
(SELECT d.Barcode,SUM(AmountTaken) AmountTaken
  FROM [Aggregation].[dbo].[DiscountPromotion] d

  GROUP BY d.Barcode

  UNION ALL

  SELECT i.Barcode,SUM(AmountTaken) AmountTaken
  FROM [Aggregation].[dbo].ItemSaleTransaction i

  group by i.Barcode)  ItemDiscountUnion

  group by Barcode

Note the original SQL is merging the 2 selects NOT concatenating them. I need to know how to merge the results i.e. removing duplicates and summing the rows amount value where there is duplication based on bar code.

Bosky answered 30/4, 2010 at 11:40 Comment(2)
msdn.microsoft.com/en-us/library/bb386979.aspxVerecund
just use the Union operator as @Ian-P suggestedJenelljenelle
U
48

Three useful Linq concepts operating on sets. Given set c and set e:

Concat gives you everything in c or e:

(From c In db.Customers Select c.Phone).Concat( _
             From c In db.Customers Select c.Fax).Concat( _
             From e In db.Employees Select e.HomePhone)

(From c In db.Customers _
            Select Name = c.CompanyName, Phone = c.Phone).Concat(From e In db.Employees _
            Select Name = e.FirstName & " " & e.LastName, Phone = e.HomePhone)

Union also gives you everything in c and e, but removes any duplicates:

(From c In db.Customers _
        Select c.Country).Union(From e In db.Employees _
        Select e.Country)

Except gives you everything in c that is not in e:

(From c In db.Customers _
             Select c.Country).Except(From e In db.Employees Select e.Country)
Underclothes answered 30/4, 2010 at 11:46 Comment(3)
Concat, Union and Except are different things: Concat will just merge two sequences into one, Union will merge but remove duplicates (distinct), and Except is completely different: it returns the elements of the first sequence that do not belong to the second sequence. (the last one is Intersect: returns the common elements from 2 sequences)Jenelljenelle
As Guillaume86 mentioned, this post is incorrect. A little wording change would easily fix the problem.Dauntless
I think it is worth noting that like Union, Except and Interset also remove any duplicates, including duplicates in the source sequences.Nide
T
13

Here's an example of a generic union, without regard to the scenario you posted:

var something =
                (from e in _repository
                 select new { e.Property1, e.Property2 }).Union(
                (from e in _repository
                 select new { e.Property1, e.Property2 }));
Tremain answered 30/4, 2010 at 14:47 Comment(0)
M
5

There are the 101 Linq Samples - with two union samples Union1 and Union2

This Linq statement should get you the same results as your SQL: (it has for me on a test record-set)

var results = (from a in (from d in DiscountPromotions
            group d by d.BarCode into g
            select new { 
                BarCode = g.Key,
                AmountTaken = g.Sum(p => p.AmountTaken)
                }).Union(from i in ItemSaleTransactions
            group i by i.BarCode into o
            select new { 
                BarCode = o.Key,
                AmountTaken = o.Sum(i => i.AmountTaken)
                }) group a by a.BarCode into b
                select new {
                    BarCode = b.Key,
                    AmountTaken = b.Sum(c => c.AmountTaken)
                });
Maquette answered 30/4, 2010 at 14:43 Comment(0)
E
0
return await (
                                 from b in _db.Brands
                                 where b.brand_id == 0
                                 select new brandInfo
                                 {
                                     brand_id = b.brand_id,
                                     brand_name = b.brand_name
                                 }).Union<brandInfo>(
                                        from pd in _db.Product_Details
                                        join b in _db.Brands on pd.brand_id equals b.brand_id
                                        where pd.cate_id == cate_id && pd.pro_id == pro_id || b.brand_id == 0
                                        select new brandInfo
                                        {
                                            brand_id = b.brand_id,
                                            brand_name = b.brand_name
                                        }
                              ).Distinct().OrderBy(o=>o.brand_name).ToListAsync();
Endstopped answered 21/6, 2023 at 11:48 Comment(0)
A
0
var discountPromotionQuery =
from d in dbContext.DiscountPromotion
group d by d.Barcode into g
select new
{
    Barcode = g.Key,
    AmountTaken = g.Sum(d => d.AmountTaken)
};

var itemSaleTransactionQuery =
from i in dbContext.ItemSaleTransaction
group i by i.Barcode into g
select new
{
    Barcode = g.Key,
    AmountTaken = g.Sum(i => i.AmountTaken)
};

var result =
(from d in discountPromotionQuery
 select new
 {
     d.Barcode,
     AmountTaken = d.AmountTaken
 })
.Concat(from i in itemSaleTransactionQuery
        select new
        {
            i.Barcode,
            AmountTaken = i.AmountTaken
        })
.GroupBy(x => x.Barcode)
.Select(g => new
{
    Barcode = g.Key,
    AmountTaken = g.Sum(x => x.AmountTaken)
})
.Take(10);
Alcohol answered 21/6, 2023 at 16:46 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.