I have two tables, as below:
I'm hoping to create a view, where the result is as per the result above. That is, the Act column is the total of all matching records between tbl1 and tbl2.
Additional explaination, graphically:
I'd left join tbl1 with an aggregate query on tbl2:
SELECT t1.id, t1.req, COALESCE(t2.act, 0) AS act
FROM tbl1 AS t1
LEFT JOIN (SELECT id, SUM(act)
FROM tbl2
GROUP BY id) t2 ON t1.id = t2.id
Related
I have 3 tables in BigQuery.
I need to join first one (contains ids), to others (contains list of values for ids). I want to have sum of values by ids from two tables:
SELECT t0.id, sum(values) FROM t0
LEFT JOIN t1 ON t0.id = t1.id
LEFT JOIN t2 ON t0.id = t2.id
GROUP BY id
It does not work with an error Column name values is ambiguous
What is the best way to make it?
SELECT t0.id, sum(t1.values) + sum(t2.values) as sumOfValues FROM t0
LEFT JOIN t1 ON t0.id = t1.id
LEFT JOIN t2 ON t0.id = t2.id
GROUP BY id
I think below better reflect your original idea
#standardSQL
SELECT id, sum(u.values)
FROM t0
LEFT JOIN (
SELECT id, values FROM t1 UNION ALL
SELECT id, values FROM t2
) u
USING (id)
GROUP BY id
I have a query which looks like this:
select id,name
from table1 as one
where one.duration < (select min(duration) from table2 where one.id = id)
Table2 contains a column called outcome and I would like to display it in the outer query. Table1 and Table2 have no relationship except for the fact that they both contain the column id.
How can I accomplish this?
You need a HAVING Clause including comparison of aggregated values for duration column together with GROUP BY expression :
SELECT t1.id, name, outcome
FROM table1 t1
JOIN table2 t2
ON t2.id = t1.id
GROUP BY t1.id, name, outcome
HAVING MAX(t1.duration) < MIN(t2.duration)
I have two tables, table1 and table2. table1 has 'id' column. table2 has 'id' and 'quantity' columns. I want to compare the same values under 'id' columns from both tables and show the value under 'quantity' column form table2.
The simple logic is "select id=1 from table1 compare with select id=1 from table2, then show the quantity value from table2". Is there any way to query this statement?
Join the tables:
SELECT *
FROM
table1 t1
INNER JOIN table2 t2
ON t1.id = t2.id
Using INNER JOIN will cause the results to show only rows where the same ID is present in both tables. If you want to show all rows from table 1 and matching rows from table 2 plus blanks for any rows where there is no table 2 id for a particular table 1 id, then use LEFT JOIN instead of INNER JOIN.
If you only want certain columns in your output you can list them:
SELECT t1.id, t2.quantity
...
etc
More about joins - for future learning
In most other database systems there exists the corollary of LEFT join; RIGHT join. If you want all rows from table 2 plus matching rows from table 1, and blanks where there is no related table 1 row, use RIGHT JOIN. SQLite doesn't support RIGHT joins, so you'll have to rewrite your query (swap the table names around) so t2 is on the LEFT. It's the table name that matters, not the order of appearance in the ON section:
--all rows from t1 plus any matching rows from t2
SELECT *
FROM
table1 t1
LEFT JOIN table2 t2
ON t1.id = t2.id
--all rows from t2 plus any matching rows from t1
SELECT *
FROM
table2 t2
LEFT JOIN table1 t1
ON t1.id = t2.id
Eventually you'll come across a FULL [OUTER] JOIN which is "all rows from t1 and any matching from t2, plus any additional rows from t2 and their possible matches from t1". SQLite doesn't support this either, but it can be emulated. Ordinarily it's emulated with a LEFT JOIN UNION RIGHT JOIN, but as SQLite doesn't support RIGHT, you'll have to emulate it with two LEFT joins, one with the tables swapped round:
--all rows from t1 plus any matching rows from t2
SELECT *
FROM
table1 t1
LEFT JOIN table2 t2
ON t1.id = t2.id
UNION
SELECT *
FROM
table2 t2
LEFT JOIN table1 t1
ON t1.id = t2.id
Cor. All that for the sake of being able to say this in e.g. SQLServer:
SELECT *
FROM
table1 t1
FULL OUTER JOIN table2 t2
ON t1.id = t2.id
I am working with two tables in a database where the first table (T1) consist of measurements from a device and the other table (T2) has the information on each individual device.
In T2 there is a column called METADATA1 which could be a description, an empty string or null.
I would like to write a query that gets all the distinct devices that have measurements in T1 and their METADATA1. I want to replace the empty/null metadata with deviceid. Here is what I have
SELECT DISTINCT(t1.DEVICEID),
COALESCE(NULLIF(t2.METADATA1,''), t1.DEVICEID) AS METADATA1
FROM T1 t1 LEFT JOIN T2 t2 ON t1.DEVICEID = t2.DEVICEID
ORDER BY t1.DEVICEID ASC
This returns zero rows and does not work. If I replace the COALESCE with COALESCE(NULLIF(t2.METADATA1,''), '0') then I get the correct number of rows.
Could someone please tell me what I am doing wrong.
Your query should be returning rows, assuming t1 has rows. I would express it using GROUP BY rather than SELECT DISTINCT.
SELECT t1.DEVICEID,
COALESCE(NULLIF(MAX(t2.METADATA1), ''), t1.DEVICEID) AS METADATA1
FROM T1 t1 LEFT JOIN
T2 t2
ON t1.DEVICEID = t2.DEVICEID
GROUP BY t1.DEVICEID
ORDER BY t1.DEVICEID ASC;
I have three tables and two seperate SQL queries which are working correctly and I am having correct results.
If I try to join these three tables I am having null as result.
First query:
select T1.ID,T3.COMPANY
from T1,T3
where (T1.status!='CLOSED') and (T1.PRIORITY)>5 and T1.CLASSID=T3.CLASSID
Second query:
SELECT T1.ID, T2.DESCRIPTION
FROM T1
LEFT OUTER JOIN T2
ON T1.ID=T2.KEY
WHERE T1.status!='CLOSED'
AND (T2.CREATEDATE= (SELECT MAX(CREATEDATE)
FROM T2
WHERE T2.KEY=T1.ID))
I tried to join them but as result I am having null:
select T1.ID,T3.COMPANY,T2.DESCRIPTION
from T1
INNER JOIN T3 ON T1.CLASSID=T3.CLASSID
LEFT OUTER JOIN T2
ON T1.ID=T2.KEY
where (T1.status!='CLOSED') AND (T1.PRIORITY)>5
AND (T2.CREATEDATE= (SELECT MAX(CREATEDATE)
FROM T2
WHERE T2.KEY=T1.ID))
like it does not recognized last part for taking MAX value from T2 table.
What am I doing wrong? Thanks for help
Firstly, use an alias for the subquery on table T2.
T2.CREATEDATE =
(SELECT MAX(T2Alias.CREATEDATE)
FROM T2 AS T2Alias
WHERE T2Alias.KEY = T1.ID)
Secondly, consider moving this condition into the ON clause of the LEFT JOIN to table T2.
The first thing that jumps out at me is the new dependency on both T1.Priority > 5 and T2.CreateDate value being equal to the result of the inline query:
( AND (T1.PRIORITY) > 5
AND (T2.CREATEDATE =
(SELECT MAX(CREATEDATE) FROM T2 WHERE T2.KEY = T1.ID) )
Without the data it's difficult to check however this may be the issue