Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL MERGE using GROUP BY

I have to do a MERGE statement but before I need to prepare the query, this query has a group by with some string columns and values, because I'm doing a group by, I can't include the primary key. How can I do my MERGE if I can't provide a primary key?

This is the query

SELECT Account,
       BillDate, 
       Name,
       SUM(ChargeAmount) AS ChargeAmount, 
       SUM(ChargeTaxes) AS ChargeTaxes,       
  FROM MyTempTable
 GROUP BY Account, BillDate, Name

Now I need to do a MERGE into my table starting from that query but I don't have a pk.

like image 829
rgx71 Avatar asked Dec 14 '12 14:12

rgx71


People also ask

Can ORDER BY and GROUP BY be used together in SQL?

Both GROUP BY and ORDER BY are clauses (or statements) that serve similar functions; that is to sort query results. However, each of these serve very different purposes; so different in fact, that they can be employed separately or together.

Can you GROUP BY 2 things in SQL?

SQL GROUP BY multiple columns is the technique using which we can retrieve the summarized result set from the database using the SQL query that involves grouping of column values done by considering more than one column as grouping criteria.

How do you group data together in SQL?

The Group By statement is used to group together any rows of a column with the same value stored in them, based on a function specified in the statement. Generally, these functions are one of the aggregate functions such as MAX() and SUM(). This statement is used with the SELECT command in SQL.


1 Answers

You can use the GROUP BY clause with the MERGE. As the documentation dictate that:

[ WITH <common_table_expression> [,...n] ]
MERGE 
    [ TOP ( expression ) [ PERCENT ] ] 
    [ INTO ] <target_table> [ WITH ( <merge_hint> ) ] [ [ AS ] table_alias ]
    USING <table_source> 
    ON <merge_search_condition>
    [ WHEN MATCHED [ AND <clause_search_condition> ]
        THEN <merge_matched> ] [...n ]
    [ WHEN NOT MATCHED [ BY TARGET ] [ AND <clause_search_condition> ]
        THEN <merge_not_matched> ]
    [ WHEN NOT MATCHED BY SOURCE [ AND <clause_search_condition> ]
        THEN <merge_matched> ] [...n ]
    [ <output_clause> ]
    [ OPTION ( <query_hint> [ ,...n ] ) ]    
;

Where the table_source can be:

<table_source> ::= 
{
    table_or_view_name [ [ AS ] table_alias ] [ <tablesample_clause> ] 
        [ WITH ( table_hint [ [ , ]...n ] ) ] 
  | rowset_function [ [ AS ] table_alias ] 
        [ ( bulk_column_alias [ ,...n ] ) ] 
  | user_defined_function [ [ AS ] table_alias ]
  | OPENXML <openxml_clause> 
  | derived_table [ AS ] table_alias [ ( column_alias [ ,...n ] ) ] 
  | <joined_table> 
  | <pivoted_table> 
  | <unpivoted_table> 
}

Therefore you can put the GROUP BY clause, the way you did in your question like so:

MERGE INTO table2 AS TGT
USING
(
  SELECT Account,
       BillDate, 
       Name,
       SUM(ChargeAmount) AS ChargeAmount, 
       SUM(ChargeTaxes) AS ChargeTaxes
  FROM table1
 GROUP BY Account, BillDate, Name
) AS SRC
  ON  SRC.Account = TGT.Account AND
      SRC.Name = TGT.Name
WHEN NOT MATCHED THEN
  INSERT (Account, BillDate, Name, ChargeAmount, ChargeTaxes)
  VALUES (SRC.Account, SRC.BillDate, 
          SRC.Name, SRC.ChargeAmount, SRC.ChargeTaxes);

SQL Fiddle Demo

like image 175
Mahmoud Gamal Avatar answered Sep 27 '22 21:09

Mahmoud Gamal