Union two tables with different column names - sql

code snippet
As you can see from the results table, the union hasn't worked properly as there is more than one row for each make of car e.g. Toyota is listed for NG and KE in row 1 and for SA in row 3. Does anyone know how to join these tables more successfully?
Thank you!

How about making your last query another CTE, then grouping and summing the cnt on the new CTE?
WITH combined AS (
select title FROM autochek_ng
union all
select title FROM autocheck_kenya)
, brands AS (
SELECT LEFT(title, CHARINDEX(' ' , title)) as brand
FROM combined )
, aggregate as (
select brand, count(brand) as cnt
from brands
group by brand
UNION ALL
select make as brand, count(make) as cnt
from south_africa5000
group by make)
select brand, sum(cnt) cnt
from aggregate
group by brand

Related

Custom table query in SQL Server similar to custom table in SPSS?

From the sample data it will compute the average price per name and code including the combinations for all names and all codes.
Currently I'm using the union all for all the combinations which is a tedious way. Is there a simplest way to query that case?
SELECT NAME ,CODE, AVG(PRICE)
FROM SAMPLE_DATA
GROUP BY
NAME ,CODE
UNION ALL
SELECT 'ALL NAMES' ,CODE, AVG(PRICE)
FROM SAMPLE_DATA
GROUP BY
CODE
UNION ALL
SELECT NAME, 'ALL CODES', AVG(PRICE)
FROM SAMPLE_DATA
GROUP BY NAME
UNION ALL
SELECT 'ALL NAMES', 'ALL CODES, AVG(PRICE)
FROM SAMPLE_DATA
You can use GROUPING SETS:
SELECT NAME, CODE, AVG(PRICE)
FROM SAMPLE_DATA
GROUP BY GROUPING SETS ( (NAME, CODE), (NAME), (CODE), () )
Just include all the combinations you want in the list.

SQL Select one row over a matching row from two tables

I have two tables with the same fields, but a final value that is calculated slightly differently. I need to combine the data from these two tables into one but need to prioritise one record over another when there is a match. Do you know how this might be possible?
Below is a mock up of two matching records:
ID Balance Type CCY Payment Final_Balance
28 1068376.037 F - CC GBP 78124 990252.0367
28 1068376.037 F - DD GBP 982905 85470.08293
Apologies if the format comes out poorly, I'm unsure how to format table data.
I have thousands of records in these two tables but for a handful of records I have the same information in both tables. Essentially what I'm trying to get to is where there is a match I want it to select F-CC over F-DD so I end up with unique records in my final table.
Thanks
I personally use ROW_NUMBER() for things like this, but there may be a better solution.
You can re-run this SQL to show how the final answer is slowly built up:
declare #t1 table (id int)
declare #t2 table (id int, txt varchar(2))
insert into #t1
select 1 union
select 2
insert into #t2
select 1, 'FC' union
select 1, 'FD' union
select 2, 'FC' union
select 2, 'FD'
select *, row_number() over (partition by id order by txt) as we_want_the_ones
from #t2
select * from (
select id, txt, row_number() over (partition by id order by txt) as we_want_the_ones
from #t2
) z
where we_want_the_ones = 1
select *
from #t1 a
join (
select * from (
select id, txt, row_number() over (partition by id order by txt) as we_want_the_ones
from #t2
) z
where we_want_the_ones = 1
) b on a.id = b.id
My understanding of the question is that you have two tables (A and B) which have the exact same columns. You want to UNION these tables into one dataset, but sometimes you have rows in the two tables which "match" each other. In this case you only take one of the rows based on some priority.
From your example it seems that..
Match: Occurs when the ID is the same.
Priority: Is based on the Type column, prioritized by lower alphabetical order.
Also I'm assuming SQL Server, since that's what I prefer and you didn't say.
Hopefully all that is correct.. Now, here is how I would approach it.
I would start by performing the UNION of the two tables. Taking all records and not worrying about matching yet, putting them in a temp table to use later.
SELECT ID, Balance, Type, CCY, Payment, Final_Balance
INTO #AllRecords
FROM A
UNION
SELECT ID, Balance, Type, CCY, Payment, Final_Balance
FROM B
Next, I would GROUP BY the fields which determine a match, then use MIN or MAX to get the correct value for priority columns. By my understanding of your problem that means..
SELECT ID, MIN(Type) AS Type
FROM #AllRecords
GROUP BY ID
With that query you now have the natural key for all the records you want to display in your final result. All that is left to do is look up the rest of the columns using those keys, we can do this by using that query as a subquery.
SELECT ID, Balance, Type, CCY, Payment, Final_Balance
FROM #AllRecords r
INNER JOIN (
SELECT ID, MIN(Type) AS Type
FROM #AllRecords
GROUP BY ID ) final ON r.ID = final.ID AND r.Type = final.Type
So all together the resulting query is..
SELECT ID, Balance, Type, CCY, Payment, Final_Balance
INTO #AllRecords
FROM A
UNION
SELECT ID, Balance, Type, CCY, Payment, Final_Balance
FROM B
SELECT ID, Balance, Type, CCY, Payment, Final_Balance
FROM #AllRecords r
INNER JOIN (
SELECT ID, MIN(Type) AS Type
FROM #AllRecords
GROUP BY ID ) final ON r.ID = final.ID AND r.Type = final.Type

SUM two SELECT COUNT Queries with GROUP BY

I have two queries in a linked database (linking tables from two different project databases). I need to combine the queries to get a total count that is grouped by Interaction_Type1. The SQL code is as follows:
Query#1:
SELECT Sum(Temp.cnt) AS SumOfcnt, Temp.Interaction_Type1
FROM (SELECT COUNT(*) as cnt, Interaction_Type1 from AMERILOCKMasterConversionTable
GROUP BY Interaction_Type1
UNION ALL
SELECT COUNT(*), Interaction_Type2 from AMERILOCKMasterConversionTable
GROUP BY Interaction_Type2
UNION ALL
SELECT COUNT(*), Interaction_Type3 from AMERILOCKMasterConversionTable
GROUP BY Interaction_Type3
) AS Temp
GROUP BY Temp.Interaction_Type1;
and Query#2
SELECT Sum(Temp.cnt) AS SumOfcnt, Temp.Interaction_Type1
FROM (SELECT COUNT(*) as cnt, Interaction_Type1 from MARKETMasterConversionTable
GROUP BY Interaction_Type1
UNION ALL
SELECT COUNT(*), Interaction_Type2 from MARKETMasterConversionTable
GROUP BY Interaction_Type2
UNION ALL
SELECT COUNT(*), Interaction_Type3 from MARKETMasterConversionTable
GROUP BY Interaction_Type3
) AS Temp
GROUP BY Temp.Interaction_Type1;
I would like the query to yeild the following results:
Interaction_Type1 Total
Left_Message 23
Made_Contact 16
Bad_Phone_Number 8
No_Answer 12
I am brand new to SQL and have researched all of this online and have had no luck in combining these two queries to produce the desired results.
Any help would be GREATLY appreciated!!
Thanks!
Red
You should have something like
SELECT Integration_Type, SUM(*)
FROM ( SELECT Integration_Type, SumOfcnt FROM VIEW1
UNION ALL
SELECT Integration_Type, SumOfcnt FROM VIEW2)
GROUP BY Integration_Type
but before create views for queries you have provided here, or just gather all your queries in single view.

select max, min values from two tables

I have two tables. Differ in that an archive is a table and the other holds the current record. These are the tables recording sales in the company. In both we have among other fields: id, name, price of sale. I need to select from both tables, the highest and lowest price for a given name. I tried to do with the query:
select name, max (price_of_sale), min (price_of_sale)
from wapzby
union
select name, max (price_of_sale), min (price_of_sale)
from wpzby
order by name
but such an inquiry draws me two records - one of the current table, one table archival. I want to chose a name for the smallest and the largest price immediately from both tables. How do I get this query?
Here's two options (MSSql compliant)
Note: UNION ALL will combine the sets without eliminating duplicates. That's a much simpler behavior than UNION.
SELECT Name, MAX(Price_Of_Sale) as MaxPrice, MIN(Price_Of_Sale) as MinPrice
FROM
(
SELECT Name, Price_Of_Sale
FROM wapzby
UNION ALL
SELECT Name, Price_Of_Sale
FROM wpzby
) as subQuery
GROUP BY Name
ORDER BY Name
This one figures out the max and min from each table before combining the set - it may be more performant to do it this way.
SELECT Name, MAX(MaxPrice) as MaxPrice, MIN(MinPrice) as MinPrice
FROM
(
SELECT Name, MAX(Price_Of_Sale) as MaxPrice, MIN(Price_Of_Sale) as MinPrice
FROM wapzby
GROUP BY Name
UNION ALL
SELECT Name, MAX(Price_Of_Sale) as MaxPrice, MIN(Price_Of_Sale) as MinPrice
FROM wpzby
GROUP BY Name
) as subQuery
GROUP BY Name
ORDER BY Name
In SQL Server you could use a subquery:
SELECT [name],
MAX([price_of_sale]) AS [MAX price_of_sale],
MIN([price_of_sale]) AS [MIN price_of_sale]
FROM (
SELECT [name],
[price_of_sale]
FROM [dbo].[wapzby]
UNION
SELECT [name],
[price_of_sale]
FROM [dbo].[wpzby]
) u
GROUP BY [name]
ORDER BY [name]
Is this more like what you want?
SELECT
a.name,
MAX (a.price_of_sale),
MIN (a.price_of_sale) ,
b.name,
MAX (b.price_of_sale),
MIN (b.price_of_sale)
FROM
wapzby a,
wpzby b
ORDER BY
a.name
It's untested but should return all your records on one row without the need for a union
SELECT MAX(value) FROM tabl1 UNION SELECT MAX(value) FROM tabl2;
SELECT MIN(value) FROM tabl1 UNION SELECT MIN(value) FROM tabl2;
SELECT (SELECT MAX(value) FROM table1 WHERE trn_type='CSL' and till='TILL01') as summ, (SELECT MAX(value) FROM table2WHERE trn_type='CSL' and till='TILL01') as summ_hist

How to put the Order BY in SQL UNION so TOTALS will show up always as last row?

I have SQL UNION where second part of that statement is the row that represents TOTALS. How can I ORDER BY where TOTALS will ALWAYS will show up as the last row?
Add an extra column to the queries being UNIONed, and make that column the first column in your ORDER BY clause.
So if I started with something like this:
SELECT product, price
FROM table
UNION
SELECT 'Total' AS product, SUM(price)
FROM table
I'd add a new column like this:
SELECT product, price
FROM (
SELECT product, price, 0 AS union_order
FROM table
UNION
SELECT 'Total' AS product, SUM(price), 1 AS union_order
FROM table
)
ORDER BY union_order
That way, regular products appear first, then the total appears at the end.
Have you tried using GROUP BY ROLLUP - it might be just want you want, although it's difficult to tell when you haven't posted your query.
You could try adding an 'order' column to each query and then order by that column...
SELECT x.*
FROM
(
SELECT columns, 2 AS [Order]
UNION
SELECT totals, 1 AS [Order]
) x
ORDER BY x.[Order]
select * from
(
select 1 as prio
, col1
, col2
...
from tableA
union
select 2 as prio
, totalCol1
, totalCol2
...
from tableB
) order by prio