Unique table from multiple ones having same and different columns (SQL) - sql

I have multiple datasets having different rows and fields.
dataset1
Customer_ID Date Category Address City School
4154124 1/2/2021 A balboa st. Canterbury Middleton
2145124 1/2/2012 A somewhere world St. Augustine
1621573 1/2/2012 A my_street somewhere St. Augustine
dataset2
Customer_ID Date Category Country Zipcode
14123 12/12/2020 B UK EW
416412 14/12/2020 B ES
dataset3
Customer_ID Date Category School University
4124123 07/12/2020 C Middleton Oxford
I would like a final dataset which includes all the columns (keeping only one copy of the common ones):
Customer_ID Date Category Address City School Country Zipcode University
4154124 1/2/2021 A balboa st. Canterbury Middleton
2145124 1/2/2012 A somewhere world St. Augustine
1621573 1/2/2012 A my_street somewhere St. Augustine
14123 12/12/2020 B UK EW
416412 14/12/2020 B ES
4124123 07/12/2020 C Middleton Oxford
would a left join be the best way to get the expected output? How I can keep Customer_ID Date and Category and duplicates column (e.g., School) only once?

You can achieve this using UNION ALL.
SELECT Customer_ID, Date, Category, Address, City, School, '' AS Country, '' AS ZipCode, '' AS university FROM dataset1
UNION ALL
SELECT Customer_ID, Date, Category, '', '', '', Country, Zipcode, '' FROM dataset2
UNION ALL
SELECT Customer_ID, Date, Category, '', '', School, '', '', University FROM dataset3

Related

Sum of column depending on values

Can you guys let me know how to make a query that output the sum of amount based on column values(order, Continent and Country)? Also, I want to show all Continent values as unique value (North America)
Example table,
ID Code Continent Country amount
----------------------------------------------------
1 1 North America NULL NULL
2 1 America USA 10
3 1 NA USA 10
4 1 Unknown USA 10
5 2 North America NULL NULL
6 2 America Canada 15
7 2 NA Canada 15
8 2 Unknown Canada 15
9 3 North America NULL NULL
10 3 America Mexico 20
11 3 NA Mexico 20
12 3 Unknown Mexico 20
Output
ID Code Continent Country SumAmount
----------------------------------------------
1 1 North America USA 30
2 2 North America Canada 45
3 3 North America Mexico 60
I have tried to approach it like
select ID, Code, case when Continent != 'North America' then Continent = 'North America' end as Continent, Country, sum(Amount) as SumAmount
from Table group by ID, Continent, Country
or maybe I need to make a query like this and work with this query below?
select ID, Code, Continent, Country, sum(Amount) as SumAmount
from Table where Continent !='North America'
But it is not working. How should I do this?
I appreciate for any other approaches. It would be better than mine
The awkward design here (relations with no real indication of such other than the shared Code column) is going to lead to suboptimal queries like this
DECLARE #ContinentToReport varchar(32) = 'North America';
;WITH x AS
(
SELECT Code FROM dbo.TableName
WHERE Continent = #ContinentToReport
AND Country IS NULL
)
SELECT ID = ROW_NUMBER() OVER (ORDER BY x.Code),
x.Code,
Continent = #ContinentToReport,
t.Country,
SumAmount = SUM(t.amount)
FROM dbo.TableName AS t
INNER JOIN x ON t.Code = x.Code
WHERE t.Country IS NOT NULL
GROUP BY x.Code, t.Country
ORDER BY x.Code;
Output (though I made a guess at what ID means and why it's different then the ID and the source, and I find the Continent column is kind of redundant since it will always be the same):
ID
Code
Continent
Country
SumAmount
1
1
North America
USA
30
2
2
North America
Canada
45
3
3
North America
Mexico
60
Example db<>fiddle
The simplest query which returns the correct result seems to be something like this
select row_number() over (order by Code) ID,
Code,
'North America' Continent,
Country,
sum(amount) SumAmount
from dbo.TableName
where Country is not null
group by Code, Country
order by Code;
dbFiddle

How to replace multiple columns in one SQL query?

I have 2 tables: country and trip.
A trip can have up to 3 country codes.
country table
country_code
country_name
FRA
FRANCE
IRL
IRELAND
JPN
JAPAN
MAR
MOROCCO
NZL
NEW ZEALAND
trip table
trip_id
country_code
country_code2
country_code3
1
FRA
IRL
JPN
2
MAR
NZL
My goal is to have country names displayed on the trip table instead of country codes.
I succeed to have only 1 country code replaced, thanks to the left join clause. I would like to have up to 3 country names displayed per row.
SELECT trip_id, country_name
FROM trip
LEFT JOIN country ON country_code = country_name
The actual output of the trip table:
trip_id
country_name
1
FRANCE
2
MOROCCO
Is there a way to replace each country code with its corresponding country name?
The EXPECTED output of the query from the trip table:
trip_id
country_name
country_name2
country_name3
1
FRANCE
IRELAND
JAPAN
2
MOROCCO
NEW ZEALAND
Thank you!
You could add two more joins
SELECT trip_id, c1.country_name, c2.country_name, c3.country_name
FROM trip t
left join
country c1
on t.country_code = c1.country_code
left join
country c2
on t.country_code2 = c2.country_code
left join
country c3
on t.country_code3 = c3.country_code
The cleanest way of accomplishing this query is using subqueries:
SELECT t.trip_id,
(SELECT country_name FROM country WHERE country_code = t.country_code) "c1",
(SELECT country_name FROM country WHERE country_code = t.countty_code2) "c2",
(SELECT country_name FROM country WHERE country_code = t.country_code3) "c3"
FROM trip t

Spliting column values into groups and summing up values from linked table

I have two tables in SQL, they are linked by Customer_ID.
customers
customer_id; account_created; company_name; city;
1 11/10/2011 abc new york
2 1/1/2018 xyz los angeles
3 11/10/2012 finance new jersey
4 21/04/2013 juices san francisco
orders
order_id; customer_id; order_date; shipping date; order_value; currency;
100 1 19/10/2019 20/10/2019 4000 USD
101 3 1/10/2019 2/10/2019 300 USD
102 2 13/11/2019 15/11/2019 7000 USD
103 4 12/9/2019 20/9/2019 100 USD
104 1 10/11/2019 12/11/2019 3000 USD
I would like to divide orders into two regions: East (contains New York, Boston and New Jersey) and West (Los Angeles, San Francisco) and then show sum of order_value for both regions in a way:
Region sum of order_value
East 10000
West 20000
Here are the tables, sorry they are in image, I can't format them (will learn asap!)
It seems really weird to call "New Jersey" as city. In any case, you want a case expression of some sort to assign the region, and then aggregation:
select (case when city in ('New York', 'Boston', 'New Jersey') then 'East'
when city in ('Los Angeles', 'San Francisco') then 'West'
else '???'
end) as region,
sum(order_value)
from customers c join
orders o
on o.customer_id = c.customer_id
group by (case when city in ('New York', 'Boston', 'New Jersey') then 'East'
when city in ('Los Angeles', 'San Francisco') then 'West'
else '???'
end)
Just add a third table with fields: City|Region
Then you just join the 3 tables and group by Region and sum your orders value.
No code needed.

Query to output customers and employees and their cities where each city must contain at least one customer and one employee

I must take sellers and customers and output them in one column, showing their cities and types.
My problem is: I don't need to output customers whose cities aren't in sellers' table and vice versa.
SELECT
ContactName, City, Type
FROM
(SELECT
'Seller' AS Type,
ContactName, City
FROM
[dbo].[Suppliers] t
GROUP BY
City, ContactName
UNION
SELECT
'Customer',
ContactName, City
FROM
[dbo].[Customers] t
GROUP BY
City, ContactName) t
GROUP BY
ContactName, City, Type
Result :
| Ivan Ivanov | Seller | Moscow |
| Piotr Petrov | Seller | Moscow |
| Ivan Romanov | Customer | Moscow |
| Johnny Bravo | Customer | London |
(let's assume there are no sellers in London therefore this column shouldn't exist)
Expected result: only columns with information where a city has at least one seller and one customer grouped by contact name and city
This seems like union all and exists:
SELECT DISTINCT c.ContactName, 'Customer' as type, c.City
FROM Customers c
WHERE EXISTS (SELECT 1 FROM Sellers s WHERE s.city = c.city)
UNION ALL
SELECT DISTINCT s.ContactName, 'Seller' as type, s.City
FROM Sellers s
WHERE EXISTS (SELECT 1 FROM Customers c WHERE c.city = s.city);
I'm not sure the SELECT DISTINCT is really needed -- I don't see why the underlying tables would have duplicates (although ContactName is not really a good column for unique identification). However, your original query has GROUP BY, suggesting that you want to eliminate duplicates.

count multiple values from single column

I have a table with customer information like date of birth, address, contactinfo, etc.
I want to count the number of customers per city with a single query that outputs two values per record, cityname and amount of customers living there:
Alabama 285
Kentucky 167
New York 4
Rio de Janeiro 950
etc...
There are hundreds of cities in the table so I can't do a
SELECT count(CASE WHEN city = 'Alabama' THEN 1 END) AS Alabama
You can use GROUP BY clause to count the number of customers per city :
SELECT city
, COUNT(*)
FROM table
GROUP BY city