In the input table the values keep changing every week. So, the next week column E would be have A instead of F and at that point I would want the E field.
So, whichever field has A has to be selected but the field having A should be the last field in the table that has an A as a record.
Input Table:
A | B | C | D | E
A A A A F
12 32 43 23 2
Output :
D
A
23
I understand that your data is unnormalized for some reason if you need a logic to get the results you can use this code:
DECLARE #table TABLE (A varchar(3), B varchar(3),C varchar(3), D varchar(3), E varchar(3))
;WITH cte
AS (SELECT ColumnName
,ColumnValue
,Row_number()
OVER(
partition BY ColumnName
ORDER BY Rn) ResultOrder
FROM (SELECT Row_number() OVER (ORDER BY (SELECT NULL))Rn,a ,b ,c ,d ,e FROM #table) p
UNPIVOT ( ColumnValue
FOR ColumnName IN( a ,b ,c ,d ,e)) AS unpvt),
cte1
AS (SELECT Ntile(5)
OVER(
ORDER BY ColumnName) ColumnId
,*
FROM cte),
cte2
AS (SELECT DISTINCT Isnull(NULLIF(ColumnId - 1, 0), 5) ColumnId
,ColumnName
FROM cte1
WHERE ColumnValue = 'F')
SELECT result
FROM (SELECT CASE ColumnId
WHEN 1 THEN 'A'
WHEN 2 THEN 'B'
WHEN 3 THEN 'C'
WHEN 4 THEN 'D'
WHEN 5 THEN 'E'
END Result
,0 ResultOrder
FROM cte2
UNION
SELECT ColumnValue
,resultorder
FROM cte1 a
WHERE EXISTS (SELECT 1
FROM cte2 b
WHERE a.ColumnId = b.ColumnId)) AS R
ORDER BY resultorder
Result For
insert #table VALUES
('A','A','A','A','F')
,('12','32','43','23','2')
A B C D E
---- ---- ---- ---- ----
A A A A F
12 32 43 23 2
result
------
D
23
A
Result For
insert #table VALUES
('F','A','A','A','A')
,('12','32','43','23','2')
A B C D E
---- ---- ---- ---- ----
F A A A A
12 32 43 23 2
result
------
E
A
2
Explanation:
CTE table does the Unpivot the table and create a row number for order the column name and the value
CT1 table creates a group base on column name using the NTILE to create 5 groups
CTE2 table get the previous column where the value is equal F
The Select Is complex to translate the ColumnId to ColumnName, if it not necessary,
you can use
SELECT ColumnValue Result
FROM cte1 a
WHERE EXISTS (SELECT 1
FROM cte2 b
WHERE a.ColumnId = b.ColumnId)
Result
------
A
23
(2 row(s) affected)
OR
SELECT ColumnValue Result
FROM cte1 a
WHERE EXISTS (SELECT 1
FROM cte2 b
WHERE a.ColumnId = b.ColumnId)
AND a.ResultOrder = 2
Result
------
23
(1 row(s) affected)
Related
I have a table in MS SQL Server, where are some null values in column "value"
Group ID Value
A 1 10
A 2
A 3
A 4 40
B 1
B 2 20
B 3 30
B 4
I want to update null values by not null in the same group with with the first higher ID, or if there is not any higher in same group, first lower. So the result should look like this.
Group ID Value
A 1 10
A 2 40
A 3 40
A 4 40
B 1 20
B 2 20
B 3 30
B 4 30
Thanks!
You can use windowed version of SUM function in order to determine islands of NULL valued records along with the record having the higher ID in the same group:
SELECT [Group], ID, Value,
SUM(CASE WHEN Value IS NULL THEN 0 ELSE 1 END) OVER
(PARTITION BY [Group] ORDER BY ID DESC) AS grp
FROM mytable
Output:
Group ID Value grp
-----------------------
A 4 40 1
A 3 30 2
A 2 NULL 2
A 1 NULL 2
B 4 40 1
B 3 NULL 1
B 2 20 2
B 1 10 3
You can now wrap the above query in a CTE and use another CTE to do the update:
;WITH CTE AS (
SELECT [Group], ID, Value,
SUM(CASE WHEN Value IS NULL THEN 0 ELSE 1 END) OVER
(PARTITION BY [Group] ORDER BY ID DESC) AS grp
FROM mytable
), ToUpdate AS (
SELECT [Group], ID, Value,
MAX(Value) OVER (PARTITION BY [Group], grp) AS group_value
FROM CTE
)
UPDATE ToUpdate
SET Value = group_value
WHERE Value IS NULL
Demo here
Edit:
The above query doesn't handle the edge case where the very last record within a Group slice is NULL. To handle this case as well you can use the following query:
;WITH CTE AS (
SELECT [Group], ID, Value,
SUM(CASE WHEN Value IS NULL THEN 0 ELSE 1 END) OVER
(PARTITION BY [Group] ORDER BY ID DESC) AS grp,
SUM(CASE WHEN Value IS NULL THEN 0 ELSE 1 END) OVER
(PARTITION BY [Group] ORDER BY ID) AS grp2
FROM mytable
), ToUpdate AS (
SELECT [Group], ID, Value,
MAX(Value) OVER (PARTITION BY [Group], grp) AS group_value,
MAX(Value) OVER (PARTITION BY [Group], grp2) AS group_value2
FROM CTE
)
UPDATE ToUpdate
SET Value = COALESCE(group_value, group_value2)
WHERE Value IS NULL
Demo here
Please try this-
DATA GENERATION
DECLARE #T TABLE
(
GroupCd CHAR(1),
Id INT,
Value INT
)
INSERT INTO #T
VALUES('A',1,10),
('A',2,NULL),
('A',3,NULL),
('A',4,40),
('B',1,NULL),
('B',2,20),
('B',3,30),
('B',4,NULL)
SOLUTION
UPDATE a
SET a.Value = b.Value
FROM #T a
INNER JOIN
(
SELECT a.GroupCd,a.Id,Coalesce(a.Value,z.Value,z1.Value) Value
FROM #T a
OUTER APPLY
(
SELECT TOP 1 Value
FROM #T b
WHERE a.GroupCd = b.GroupCd
AND b.Value IS NOT NULL AND a.Id < b.Id
ORDER BY Id
)z
OUTER APPLY
(
SELECT TOP 1 Value
FROM #T b
WHERE a.GroupCd = b.GroupCd
AND b.Value IS NOT NULL AND a.Id > b.Id
ORDER BY Id DESC
)z1
)b ON a.GroupCd = b.GroupCd AND a.Id = b.Id
SELECT * FROM #T
OUTPUT
GroupCd Id Value
------- ----------- -----------
A 1 10
A 2 40
A 3 40
A 4 40
B 1 20
B 2 20
B 3 30
B 4 30
(8 rows affected)
You Can try This simple Method
DECLARE #T TABLE
(
GroupCd CHAR(1),
Id INT,
Value INT
)
INSERT INTO #T
VALUES('A',1,NULL),
('A',2,NULL),
('A',3,30),
('A',4,40),
('B',1,10),
('B',2,20),
('B',3,NULL),
('B',4,40)
SELECT
*,
NewVal = COALESCE(Value,(SELECT TOP 1 Value FROM #T WHERE GroupCd = T.GroupCd AND Id > T.Id AND Value IS NOT NULL ORDER BY Id ASC))
FROM #T T
My Result
update MY_TABLE set [value] = [newValue] from (
select [Group] [newGroup],
[Value] [newValue]
from (
select [Group], [Value],
row_number() over (partition by [group] order by [Id] desc) [rn]
from MY_TABLE
where [Value] is not null
) [a] where [rn] = 1
) where [Group] = [newGroup] and [Value] is null
I have a table like the following
Name Age VisitedStaes
-----------------------------
A 20 NY, NJ, IL
B 25
C 25 NY, IL
Is this possible to generate the following type of result using SQL (Microsoft SQL Server)?
I mean, if the column (VisitedStaes) has multipele values sperated by comma, it will create row based on the cell values of that column
Name Age VisitedStaes
-----------------------------
A 20 NY
A 20 NJ
A 20 IL
B 25
C 25 NY
C 25 IL
Update:
I am trying to do that but still now I did not find any solution
Thanks
I applied with the function (#scsimon) but the problem is it is only able to do for some of the columns. Not for all of the columns like the following picture.
Using a splitter...
declare #table table (Name char(1), Age int, VisitedStates varchar(64))
insert into #table
values
('A',20,'NY, NJ, IL'),
('B',25,NULL),
('C',25,'NY, IL')
select
Name,
Age,
ltrim(Item) as VisitedStates
from
#table
cross apply dbo.DelimitedSplit8K(VisitedStates,',') x
RETURNS
+------+-----+---------------+
| Name | Age | VisitedStates |
+------+-----+---------------+
| A | 20 | NY |
| A | 20 | NJ |
| A | 20 | IL |
| B | 25 | NULL |
| C | 25 | NY |
| C | 25 | IL |
+------+-----+---------------+
Jeff Moden Splitter
CREATE FUNCTION [dbo].[DelimitedSplit8K] (#pString VARCHAR(8000), #pDelimiter CHAR(1))
--WARNING!!! DO NOT USE MAX DATA-TYPES HERE! IT WILL KILL PERFORMANCE!
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
/* "Inline" CTE Driven "Tally Table" produces values from 1 up to 10,000...
enough to cover VARCHAR(8000)*/
WITH E1(N) AS (
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
), --10E+1 or 10 rows
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS (--==== This provides the "base" CTE and limits the number of rows right up front
-- for both a performance gain and prevention of accidental "overruns"
SELECT TOP (ISNULL(DATALENGTH(#pString),0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
),
cteStart(N1) AS (--==== This returns N+1 (starting position of each "element" just once for each delimiter)
SELECT 1 UNION ALL
SELECT t.N+1 FROM cteTally t WHERE SUBSTRING(#pString,t.N,1) = #pDelimiter
),
cteLen(N1,L1) AS(--==== Return start and length (for use in substring)
SELECT s.N1,
ISNULL(NULLIF(CHARINDEX(#pDelimiter,#pString,s.N1),0)-s.N1,8000)
FROM cteStart s
)
--===== Do the actual split. The ISNULL/NULLIF combo handles the length for the final element when no delimiter is found.
SELECT ItemNumber = ROW_NUMBER() OVER(ORDER BY l.N1),
Item = SUBSTRING(#pString, l.N1, l.L1)
FROM cteLen l
;
GO
Scismon would be my first choice. Everyone should have a good splitter +1
However, you can't use, or want a UDF, consider the following
Example
Select A.Name
,A.Age
,VisitedStates = B.RetVal
From YourTable A
Outer Apply (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B2.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace(A.VisitedStates,',','</x><x>')+'</x>' as xml).query('.')) as B1
Cross Apply x.nodes('x') AS B2(i)
) B
Returns
Name Age VisitedStates
A 20 NY
A 20 NJ
A 20 IL
B 25 NULL
C 25 NY
C 25 IL
If you are using SQL Server 2016 or above then you can use String_split as below:
Select * from #data
cross apply string_split(visitedstates,',')
If <= 2016 then you can query as below:
Select [Name], Age, [Value] from (
Select *, xm = CAST('<x>' + REPLACE((SELECT REPLACE(visitedstates,', ','$$$SSText$$$') AS [*] FOR XML PATH('')),'$$$SSText$$$','</x><x>')+ '</x>' AS XML)
from #data ) d
cross apply (
SELECT N.value(N'text()[1]', N'nvarchar(MAX)') as value FROM xm.nodes(N'x') as T(N)
) a
For each group, grouped using field GRP, I would like to retrieve the most frequently occurring value in column A and the most frequently occurring value in column B, and potentially do this for many other columns.
Sample Data:
GRP | A | B
-----------
Cat | 1 | 1
Cat | 2 | 1
Cat | 3 | 2
Cat | 3 | 3
Dog | 5 | 6
Dog | 5 | 7
Dog | 6 | 7
Expected Output:
GRP | A | B
-----------
Cat | 3 | 1
Dog | 5 | 7
This query achieves that result:
SELECT
freq1.GRP,
freq1.A,
freq2.B
FROM (
SELECT
GRP,
A,
ROW_NUMBER() OVER(PARTITION BY GRP ORDER BY COUNT(*) DESC) AS F_RANK
FROM MyTable
GROUP BY GRP, A
) AS freq1
INNER JOIN (
SELECT
GRP,
B,
ROW_NUMBER() OVER(PARTITION BY GRP ORDER BY COUNT(*) DESC) AS F_RANK
FROM MyTable
GROUP BY GRP, B
) AS freq2 ON freq2.GRP = freq1.GRP
WHERE freq1.F_RANK = 1 AND freq2.F_RANK = 1
It just doesn't look very efficient, and even less so if I were to add a column C, D, etc...
Is there a better way?
I wouldn't say this approach is "better" because it will generate the exact same execution plan. However, I find this type of approach a lot more maintainable as the number of columns might grow. For me this is a lot easier to read.
with GroupA as
(
select Grp
, A
, ROW_NUMBER() over(partition by grp order by count(*) desc) as RowNum
from MyTable
group by Grp, A
)
, GroupB as
(
select Grp
, B
, ROW_NUMBER() over(partition by grp order by count(*) desc) as RowNum
from MyTable
group by Grp, B
)
select a.Grp
, a.A
, b.B
from GroupA a
inner join GroupB b on a.Grp = b.Grp and b.RowNum = 1
where a.RowNum = 1;
An alternative using results ranked in a temp table:
SELECT GRP, A, B,
ROW_NUMBER() OVER (PARTITION BY A ORDER BY GRP, A) ARank,
ROW_NUMBER() OVER (PARTITION BY B ORDER BY GRP, B) BRank
INTO #TMP
FROM MyTable
SELECT t1.GRP,
(SELECT TOP 1 A FROM #TMP WHERE GRP = t1.Grp ORDER BY ARank DESC) A,
(SELECT TOP 1 B FROM #TMP WHERE GRP = t1.Grp ORDER BY BRank DESC) B
FROM MyTable t1
GROUP BY T1.GRP
DROP TABLE #TMP
Full Solution on SQL Fiddle
Schema Setup:
CREATE TABLE MyTable
([GRP] varchar(3), [A] int, [B] int)
;
INSERT INTO MyTable
([GRP], [A], [B])
VALUES
('Cat', 1, 1),
('Cat', 2, 1),
('Cat', 3, 2),
('Cat', 3, 3),
('Dog', 5, 6),
('Dog', 5, 7),
('Dog', 6, 7)
;
Query 1:
SELECT GRP, A, B,
ROW_NUMBER() OVER (PARTITION BY A ORDER BY GRP, A) ARank,
ROW_NUMBER() OVER (PARTITION BY B ORDER BY GRP, B) BRank
INTO #TMP
FROM MyTable
SELECT t1.GRP,
(SELECT TOP 1 A FROM #TMP WHERE GRP = t1.Grp ORDER BY ARank DESC) A,
(SELECT TOP 1 B FROM #TMP WHERE GRP = t1.Grp ORDER BY BRank DESC) B
FROM MyTable t1
GROUP BY T1.GRP
DROP TABLE #TMP
Results:
| GRP | A | B |
|-----|---|---|
| Cat | 3 | 1 |
| Dog | 5 | 7 |
I'll start out this answer by saying this is NOT going to be more efficient to run - it should just be easier to add/subtract columns. To do this you just add them into the code in two places.
You can use dynamic SQL to build your result set like this:
CREATE TABLE ##fields (id INT IDENTITY(1,1),fieldname VARCHAR(255))
INSERT INTO ##fields
( fieldname )
VALUES ('A'),('B') --Add field names here
DECLARE #maxid INT
SELECT #maxid = MAX(id) FROM ##fields
CREATE TABLE ##Output (GRP VARCHAR(3), A INT, B INT) --Add field names here
INSERT INTO ##Output
( GRP )
SELECT DISTINCT GRP FROM MyTable
DECLARE #SQL NVARCHAR(MAX)
DECLARE #i INT = 1
WHILE #i <=#maxid
BEGIN
SELECT #SQL = 'with cte as (SELECT GRP , ' + fieldname + ' ,
ROW_NUMBER() OVER ( PARTITION BY GRP ORDER BY COUNT(*) DESC ) AS F_RANK
FROM MyTable
GROUP BY GRP , ' + fieldname + ')
UPDATE O
SET O.' + fieldname + ' = cte.' + fieldname + '
FROM ##Output O
INNER JOIN cte ON O.GRP = cte.GRP AND cte.F_Rank = 1' FROM ##fields WHERE id = #i
EXEC sp_executesql #sql
SET #i = #i + 1
END
SELECT *
FROM ##Output
DROP TABLE ##fields
DROP TABLE ##Output
Using your simple example above, I received the following performance stats:
Dynamic SQL
CPU = 31
Reads = 504
Duration = 39
Your SQL
CPU = 0
Reads = 6
Duration = 1
Clearly, this way is not a more efficient way of doing this. I did want to throw it out there anyway as an alternative to your current method.
First we create the test data:
DECLARE #MyTable TABLE
(
GRP varchar(10),
A int,
B int
)
INSERT INTO #MyTable
( GRP, A, B)
VALUES
('Cat', 1, 1),
('Cat', 2, 1),
('Cat', 3, 2),
('Cat', 3, 3),
('Dog', 5, 6),
('Dog', 5, 7),
('Dog', 6, 7);
Now we use first_value from a subselect (or a cte if you wanted) and grab the top cat and dog columns
SELECT DISTINCT
GRP,
FIRST_VALUE(A) OVER(PARTITION BY GRP ORDER BY d.A_CNT DESC) AS A_RANK,
FIRST_VALUE(B) OVER(PARTITION BY GRP ORDER BY d.B_CNT DESC) AS B_RANK
FROM
(
SELECT
GRP,
A,
ROW_NUMBER() OVER (PARTITION BY A ORDER BY GRP, A) AS A_CNT,
B,
ROW_NUMBER() OVER (PARTITION BY B ORDER BY GRP, B) AS B_CNT
FROM #MyTable
) d
Output:
GRP A_RANK B_RANK
Cat 3 1
Dog 5 7
here is the link of the picture:
help i need to create something like table 3..
i already have a query that has them all except for the count2 column, i don't know how to create that in query..
here's my code in query:
SELECT a.rn,'',a.id, b.iddesc
INTO #x
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [desc]) AS rn, *
FROM aa
) a, bb AS b
WHERE b.idcon = a.id
SELECT *
FROM #x
sorry i don't know how to explain it well,
Try this one -
Query:
DECLARE #table_a TABLE (id INT, [desc] NVARCHAR(50))
INSERT INTO #table_a (id, [desc])
VALUES
(221, 'aaa'),(222, 'sss'),
(223, 'ddd'),(225, 'fff')
DECLARE #table_b TABLE (idcon INT, iddesc NVARCHAR(50))
INSERT INTO #table_b (idcon, iddesc)
VALUES
(221, 'zxc'),(221, 'sad'),
(221, 'fdfg'),
(222, 'asd'),(222, 'vcx'),
(223, 'zxc'),(223, 'asd'),
(224, 'cxv'),(224, 'asd'),
(225, 'zcx'),(225, 'asd'),
(225, 'qwe'),(225, 'wer')
SELECT
idcon
, [desc] = iddesc
, count1
, count2 = ROW_NUMBER() OVER (PARTITION BY id ORDER BY [desc]) - 1
FROM (
SELECT *, count1 = ROW_NUMBER() OVER (ORDER BY id)
FROM #table_a
) a
JOIN #table_b ON id = idcon
Results:
idcon desc count1 count2
------- ------ ------- -------
221 zxc 1 0
221 sad 1 1
221 fdfg 1 2
222 asd 2 0
222 vcx 2 1
223 zxc 3 0
223 asd 3 1
225 zcx 4 0
225 asd 4 1
225 qwe 4 2
225 wer 4 3
Try this
SELECT
DENSE_RANK() OVER (ORDER BY idcon) AS Count1
, (ROW_NUMBER() OVER (PARTITION BY idcon ORDER BY idcon)) - 1 AS Count2
, idcon
, iddesc
FROM Table_b b
INNER JOIN Table_a a ON a.ID = b.idcon
Here is SQLFiddle demo
I have a large database and am putting together a report of the data. I have aggregated and summed the data from many tables to get two tables that look like the following.
id | code | value id | code | value
13 | AA | 0.5 13 | AC | 2.0
13 | AB | 1.0 14 | AB | 1.5
14 | AA | 2.0 13 | AA | 0.5
15 | AB | 0.5 15 | AB | 3.0
15 | AD | 1.5 15 | AA | 1.0
I need to get a list of id's, with the code (sumed from both tables) with the largest value.
13 | AC
14 | AA
15 | AB
There are 4-6 thousand records and it is not possible to change the original tables. I'm not too worried about performance as I only need to run it a few times a year.
edit:
Let me see if I can explain a bit more clearly, imagine the id is the customer id, the code is who they ordered from and the value is how much they spent there.
I need a list of the all the customer id's and the store that customer spent the most money at (and if they spent the same at two different stores, put a value such as 'ZZ' in for the store name).
try this:
DECLARE #Table1 table (id int, code char(2), value decimal(5,1))
INSERT #Table1 VALUES (13 , 'AA' , 0.5)
INSERT #Table1 VALUES (13 , 'AB' , 1.0)
INSERT #Table1 VALUES (14 , 'AA' , 2.0)
INSERT #Table1 VALUES (15 , 'AB' , 0.5)
INSERT #Table1 VALUES (15 , 'AD' , 1.5)
DECLARE #Table2 table (id int, code char(2), value decimal(5,1))
INSERT #Table2 VALUES (13 , 'AC' , 2.0)
INSERT #Table2 VALUES (14 , 'AB' , 1.5)
INSERT #Table2 VALUES (13 , 'AA' , 0.5)
INSERT #Table2 VALUES (15 , 'AB' , 3.0)
INSERT #Table2 VALUES (15 , 'AA' , 1.0)
SELECT
dt.id, MAX(dt.code) AS code, sum(dt.value) as value
from (select id, code, value
from #Table1
UNION ALL
select
id, code, value
from #Table2
) dt
group by dt.id
order by id
OUTPUT:
id code value
----------- ---- ---------------------------------------
13 AC 4.0
14 AB 3.5
15 AD 6.0
(3 row(s) affected)
I'm not sure what you are after? this is the MAX code per id summing the value. if this is not what you are after please specify i nthe question more clearly
EDIT after OP's edit, using same tables as code from above:
;WITH AllTAbles AS
(select
id, code, value
from #Table1
UNION ALL
select
id, code, value
from #Table2
)
, MaxValues AS
(SELECT
dt.id, MAX(dt.value) as MaxValue, SUM(dt.value) AS SumValue
from AllTAbles dt
group by dt.id
)
, StoreCount AS
(SELECT
a.id,a.Code, COUNT(*) AS StoreCount
FROM AllTAbles a
INNER JOIN MaxValues m ON a.id=m.id AND a.value=m.MaxValue
GROUP BY a.id,a.Code
)
SELECT
s.id
,CASE
WHEN s.StoreCount=1 THEN s.Code
ELSE 'ZZ'
END AS code
,m.SumValue
FROM StoreCount s
INNER JOIN MaxValues m ON s.id=m.id
ORDER BY s.id
OUTPUT:
id code SumValue
----------- ---- ----------
13 AC 4.0
14 AA 3.5
15 AB 6.0
(3 row(s) affected)
OP doesn't say the version of SQL Server, so here is a pre SQL Server 2005 version that does not use CTEs, has same output as the CTE version above:
SELECT
s.id
,CASE
WHEN s.StoreCount=1 THEN s.Code
ELSE 'ZZ'
END AS code
,s.SumValue
FROM (SELECT
a.id,a.Code, COUNT(*) AS StoreCount, m.SumValue
FROM (select
id, code, value
from #Table1
UNION ALL
select
id, code, value
from #Table2
) a
INNER JOIN (SELECT
dt.id, MAX(dt.value) as MaxValue, SUM(dt.value) AS SumValue
from (select
id, code, value
from #Table1
UNION ALL
select
id, code, value
from #Table2
) dt
group by dt.id
) m ON a.id=m.id AND a.value=m.MaxValue
GROUP BY a.id,a.Code,m.SumValue
) s
ORDER BY s.id
select id, code, sum(value) as value
from
(
select id, code, value
from yyy
UNION
select id, code, value
from zzz
) aaa
group by id, code
order by sum(value)
or this removing id from the grouping:
select code, sum(value) as value
from
(
select id, code, value
from yyy
UNION
select id, code, value
from zzz
) aaa
group by code
order by sum(value)