How to use SQL to output latest info with multiple columns - sql

I have a "weather" table below with 3 cols:
City Temperature Date
New York 22 C 10/10/2005
Seattle 21 C 10/10/2005
New York 18 C 10/09/2005
Seattle 20 C 10/09/2005
Washington 17 C 10/09/2005
New York 21 C 10/08/2005
Washington 20 C 10/08/2005
I want to find out the latest info on the City and Temperature in 3 cols as well (see example):
City Temperature Date
New York 22 C 10/10/2005
Seattle 21 C 10/10/2005
Washington 17 C 10/09/2005
Can anyone help?

Find the maximum (latest) date for each city in a sub-query then join on the date and city:
select weather.*
from weather
inner join
(select city, max(date) from weather group by city) as latest
on weather.date = latest.date
and weather.city = latest.city

There are several methods. Personally, I think the following is the most expressive:
SELECT * FROM weather w1 WHERE NOT EXISTS
(SELECT * FROM weather w2 WHERE w2.city = w1.city AND w2.date > w1.date)

Option 1:
select city, temparature, date
from weather t1
where date = (select max(date)
from weather t2
where t2.city=t1.city)
Option 2:
select t1.city, t1.temp, t1.date
from weather t1
where not exists (select 1
from weather t2
where t2.date > t1.date and t1.city=t2.city)

Related

How to join two total tables using sql?

For a university work we have two tables in sql:
table1:
column_name1 number_P1
PARIS 10
LISBOA 20
RIO 30
table2:
column_name2 number_P2
PARIS 100
NEW YORK 300
I need to join the two tables by adding the total number of people in each city. So I tried to do:
SELECT table1.column_name1,
number_P2 + number_P1 AS TOTAL
FROM table1
LEFT JOIN table2 ON table1.column_name = table2.column_name;
However, if a city A appears in table 1 and does not appear in table 2 this would not work. The same would happen if a City B appears in table 2 and does not appear in table 1. How can I generalize these situations?
Desired output:
column_name number_P
PARIS 110
LISBOA 20
RIO 30
NEW YORK 300
We can try to use UNION ALL with SUM instead of JOIN
SELECT column_name,
SUM(number_P) number_P
FROM (
SELECT column_name1 as column_name,number_P1 as number_P
FROM table1
UNION ALL
SELECT column_name2,number_P2
FROM table2
) t1
GROUP BY column_name
Another way to achieve this without a subquery.
SELECT IFNULL(table1.column_name1,table2.column_name2) AS ColumnName,
(IFNULL(number_P2,0)+ IFNULL(number_P1,0)) AS TOTAL
FROM table1
FULL JOIN table2 ON table1.column_name1 = table2.column_name2;
Output
ColumnName
TOTAL
PARIS
110
LISBOA
20
RIO
30
NEW YORK
300
To replace 'RIO' with 'RIO DE JANEIRO'
SELECT CASE IFNULL(table1.column_name1,table2.column_name2)
WHEN 'RIO' THEN 'RIO DE JANEIRO'
ELSE IFNULL(table1.column_name1,table2.column_name2) END AS ColumnName,
(IFNULL(number_P2,0)+ IFNULL(number_P1,0)) AS TOTAL
FROM table1
FULL JOIN table2 ON table1.column_name1 = table2.column_name2;

Selecting records from table A based in multiple records in B

I have the following sales structure. Managers are assigned a salesperson per region but also sell themselves. The table below holds the link between managers and salespersons/regions.
TABLE: MSR
Manager
Sales
Region
MA
SA
EAST
MA
SB
EAST
MA
SB
NORTH
MB
SA
WEST
MB
SB
WEST
This table lists the orders that each person scored.
TABLE: ORD
OrderId
Sales
Region
1
MA
EAST
2
MA
WEST
3
SA
WEST
4
SA
EAST
5
SB
EAST
6
SB
WEST
7
MB
NORTH
8
SB
NORTH
I want an order output per manager. For example for manager MA it would look like this:
OrderId
Sales
Region
1
MA
EAST
2
MA
WEST
4
SA
EAST
5
SB
EAST
8
SB
NORTH
For MB it looks like this:
OrderId
Sales
Region
3
SA
WEST
6
SB
WEST
7
MB
NORTH
Is there an SQL statement that can produce this result?
If for any reason you need to return/use the manager, you can use something like the following:
SELECT ORD.*, IFNULL(MSR.Manager,ORD.Sales) as ActualManager
FROM ORD
LEFT JOIN MSR
ON (ORD.Sales = MSR.Sales and ORD.Region = MSR.Region)
WHERE IFNULL(MSR.Manager,ORD.Sales) = 'MA'
ORDER BY OrderId
The below query would get you the results you want, you would just have to swap out the where to be whatever manager that you were looking for, this returns what you're looking for, for MA.
SELECT Distinct A.OrderId, A.Sales, A.Region FROM ORD a
left join MSR b on (a.Sales = b.Sales OR B.Manager = A.Sales) and a.Region = B.Region
where B.Manager = 'MA' or A.Sales = 'MA'
order by orderid asc
With cte_MA as (
Select Distinct sales from mar where manager = 'MA'
Union
Select Distinct manager from mar where manager = 'MA' ),
Cte_MB as (
Select Distinct sales from mar where manager = 'MB'
Union
Select Distinct manager from mar where manager = 'MB'),
Cte_MAorder as (
Select a orderid, a.sales, a region from ord a inner cte_MA b on a.sales = b.sales),
Cte_MBorder as (
Select a.orderid, a.sales, a.region from ord a inner cte_MB b on a.sales = b.sales)
select * from cte_MAorder;
Select * from cte_MBorder;
You should run all query with to up select query if you run select * from cte_maorder query you get MA assigned salesperson order list
you run select * from cte_mborder query you get MB assigned salesperson order list

BigQuery join a nested table onto another table

I am trying to join a table of some project data (table1) with a nested array of project id's onto another table with project data (table2) (order is important here)
table1
proj_date num_proj_per_day proj_size proj_id(nested)
1/1/2020 4 150 a123
b456
c789
table2
proj_id(not nested) proj_loc lots_of_other_proj_fields....
a123 Los Angeles
b456 New York
c798 Los Angeles
d012 Denver
.... ....
desired outcome
proj_date num_proj_per_day proj_size proj_id(unnested) pro_loc
1/1/2020 4 150 a123 Los Angeles
1/1/2020 4 150 b456 New York
1/1/2020 4 150 c789 Los Angeles
I have been able to achieve this outcome if I write the sql code with table1 as the from and then cross join unnest(proj_id) and then left join table2. The problem is i need to have table2 in the from statement then join table1 on the unnested(proj_id). Order unfortuantely matters because I have to merge this new dataset(table1) into existing dataset/framework(table2) within Looker
Example of what works to get the correct outcome but does not work for my application
SELECT
table1.*,
table2.proj_loc
FROM table1
CROSS JOIN UNNEST(table1.proj_id) as unnested
LEFT JOIN table2
ON table2.proj_id = unnested.proj_id
I am looking for something like below but you can not put the unnest into the ON clause - bigquery pops error "Unexpected keyword UNNEST"
SELECT
table1.*,
table2.proj_loc
FROM table2
LEFT JOIN table1
ON UNNEST(table1.proj_id)=table2.proj_id
Thank you in advance and let me know if you need anymore clarifying information
Below is for BigQuery Standard SQL
#standardSQL
SELECT proj_date, num_proj_per_day, proj_size, t2.*
FROM `project.dataset.table2` t2
JOIN `project.dataset.table1` t1
ON t2.proj_id IN UNNEST(t1.proj_id)
You can test, play with above using sample data from your question as in below example
#standardSQL
WITH `project.dataset.table1` AS (
SELECT DATE '2020-01-01' proj_date, 4 num_proj_per_day, 150 proj_size, ['a123','b456','c789'] proj_id
),`project.dataset.table2` AS (
SELECT 'a123' proj_id, 'Los Angeles' proj_loc, 1 proj_field1, 2 proj_field2, 3 proj_field3 UNION ALL
SELECT 'b456', 'New York', 21, 22, 23 UNION ALL
SELECT 'c789', 'Los Angeles', 31, 32, 33 UNION ALL
SELECT 'd012', 'Denver', 41, 42, 43
)
SELECT proj_date, num_proj_per_day, proj_size, t2.*
FROM `project.dataset.table2` t2
JOIN `project.dataset.table1` t1
ON t2.proj_id IN UNNEST(t1.proj_id)
with output
Row proj_date num_proj_per_day proj_size proj_id proj_loc proj_field1 proj_field2 proj_field3
1 2020-01-01 4 150 a123 Los Angeles 1 2 3
2 2020-01-01 4 150 b456 New York 21 22 23
3 2020-01-01 4 150 c789 Los Angeles 31 32 33

How to write a correct SQL query?

I have a table with following columns:
city name, population, year (year is when the data about population was collected)
In the table there can be the same city for more than 1 year, for example:
New York 7999999 2019
New York 8000000 2020
New York 7999998 2018
London 7000000 2020
London 7000000 2016
Moscow 12000000 2017
(So there're 3 records about New York, 2 about London and 1 about Moscow)
I need a query to get the newest records about every city.
So here the result will be:
New York 8000000 2020
London 7000000 2020
Moscow 12000000 2017
You want the latest record per city. A cross-database solution that usually performs well is to filter with a correlated subquery:
select t.*
from mytable t
where t.year = (select max(t1.year) from mytable t1 where t1.town = t.town)
A multi-column index on (town, year) would speed up this query.
you can use something like this:
SELECT town, amount, date FROM townlist
WHERE date IN (SELECT max(date) FROM townlist)
In general you need a solution to group the list by town - with the newest entry on top: another approach
SELECT town, amount, date
FROM (SELECT * FROM townlist ORDER BY date DESC) as sortedTable
GROUP BY town

SQL query required [duplicate]

This question already has answers here:
Single SQL query required [closed]
(3 answers)
Closed 9 years ago.
I have two tables as follows
companyid name
1 pwc
2 dell
3 microsoft
4 google
5 yahoo
6 twitter
companyid state month powerconsumption
1 newyork jan 240
2 california jan 130
3 arizona jan 210
4 texas jan 130
5 texas jan 650
6 california jan 310
2 arizona jan 340
I want to have a query to list the company in each state which consumed maximum power in the month of jan.So the result in case of above data will be
arizona dell 340
california twitter 310
newyork pwc 240
texas yahoo 650
SELECT DISTINCT (SELECT name FROM company WHERE (companyid = (SELECT TOP (1) companyid FROM consumption WHERE (state = a.state) AND (month = a.month) ORDER BY powerconsumption DESC))) AS company,
state,
month,
(SELECT TOP (1) powerconsumption FROM consumption AS consumption_1 WHERE (state = a.state) AND (month = a.month) ORDER BY powerconsumption DESC) AS powerconsumption
FROM dbo.consumption AS a
Try this query:
SELECT x.State,
c.Name AS CompanyName,
x.PowerConsumption
FROM
(
SELECT pc.CompanyID, pc.State, pc.PowerConsumption,
DENSE_RANK() OVER(PARTITION BY pc.State ORDER BY pc.PowerConsumption DESC) AS Rnk
FROM dbo.PowerConsumptionTable pc
WHERE pc.Month = 'jan'
) x INNER JOIN dbo.CompanyTable c ON x.CompanyID = c.CompanyID
WHERE x.Rnk = 1
I got an answer and that seems the best way for me. It is having a sub query,but i don't see a way to avoid that.
select t2.state,t1.name,t2.powerconsumption
FROM table1 t1
JOIN table2 t2
ON t1.companyid =t2.companyid
where t2.powerconsumption =(select MAX(t3.powerconsumption) from table2 t3 where t3.state=t2.state and t3.month='jan')
SQL Fiddle