How to write BigQuery/SQL query to divide average of a column in one table from column in second/another table - sql

I am looking for SQL query to SELECT ratio of Value1/Value2 from two tables as below..
Table_1:
-------
id Type Count
1. A. 2
2. B. 3
3. A. 1
4. A. 4
5. B. 2
Table_2:
id Type Max
1. A. 10
2. B. 10
where Value1 = SELECT AVG(Count) FROM Table_1 GROUP BY Type
and Value2 = SELECT Max FROM Table_2.
I tried below query
WITH table1 (SELECT AVG(Count) as avg_cnt...),
table2 (SELECT Max as max_val....)
SELECT table1.avg_cnt/table2.max_val
FROM ..
But it did not work.

You can just aggregate and calculate:
select t2.type, avg(t1.count) / t2.max
from table1 t1 join
table2 t2
on t1.type = t2.type
group by t2.type, t2.max;
No subqueries or CTEs are needed.

You can try using join
Select cnt/maxval
from
(
select type,avg(count) cnt
from table1
group by type
)A join table2 on table1.type=table2.type

Related

How to know if an element matches every in another table in SQL

I have the following problem in SQL:
I have a table with only 1 column containing different values: [A, B, C, D] for example
And in other table I have 2 columns with:
1 | A
1 | C
2 | D
1 | B
2 | D
1 | D
...
I need to return 1, because is the only item that matches every value in the other table, how do I do this? Thank you :)
here is the solution , you compare number of rows in your second table with number of rows in your first table,
I'm using distinct to make sure if there is a duplicate it wouldn't be counted:
SELECT id
FROM
table2
WHERE word in (select word from table1)
GROUP BY id
HAVING COUNT(DISTINCT word) = ( SELECT COUNT(*) FROM table1)
You can use aggregation:
select col1
from table1 t1
where col2 in (select col2 from table2)
group by col1
having count(*) = (select count(*) from table2);
This assumes that the col1/col2 columns are unique in table1. If not, use count(distinct) in the having clause.
Yet another option is to use left outer join and analytical function as follows:
Select id, word from
(Select t2.*,
Count(distinct t1.word) over () as total_words,
Count(distinct t2.word) over (partition by t2.id) as total_words_per_id
From table1 t1
Left Join table2 t2 on t1.word = t2.word)
Where total_words = total_words_per_id

Joining and grouping to equate on two tables

I've tried to minify this problem as much as possible. I've got two tables which share some Id's (among other columns)
id id
---- ----
1 1
1 1
2 1
2
2
Firstly, I can get each table to resolve to a simple count of how many of each Id there is:
select id, count(*) from tbl1 group by id
select id, count(*) from tbl2 group by id
id | tbl1-count id | tbl2-count
--------------- ---------------
1 2 1 3
2 1 2 2
but then I'm at a loss, I'm trying to get the following output which shows the count from tbl2 for each id, divided by the count from tbl1 for the same id:
id | count of id in tbl2 / count of id in tbl1
==========
1 | 1.5
2 | 2
So far I've got this:
select tbl1.Id, tbl2.Id, count(*)
from tbl1
join tbl2 on tbl1.Id = tbl2.Id
group by tbl1.Id, tbl2.Id
which just gives me... well... something nowhere near what I need, to be honest! I was trying count(tbl1.Id), count(tbl2.Id) but get the same multiplied amount (because I'm joining I guess?) - I can't get the individual representations into individual columns where I can do the division.
This gives consideration to your naming of tables -- the query from tbl2 needs to be first so the results will include all records from tbl2. The LEFT JOIN will include all results from the first query, but only join those results that exist in tbl1. (Alternatively, you could use a FULL OUTER JOIN or UNION both results together in the first query.) I also added an IIF to give you an option if there are no records in tbl1 (dividing by null would produce null anyway, but you can do what you want).
Counts are cast as decimal so that the ratio will be returned as a decimal. You can adjust precision as required.
SELECT tb2.id, tb2.table2Count, tb1.table1Count,
IIF(ISNULL(tb1.table1Count, 0) != 0, tb2.table2Count / tb1.table1Count, null) AS ratio
FROM (
SELECT id, CAST(COUNT(1) AS DECIMAL(18, 5)) AS table2Count
FROM tbl2
GROUP BY id
) AS tb2
LEFT JOIN (
SELECT id, CAST(COUNT(1) AS DECIMAL(18, 5)) AS table1Count
FROM tbl1
GROUP BY id
) AS tb1 ON tb1.id = tb2.id
(A subqquery with a LEFT JOIN will allow the query optimizer to determine how to generate the results and will generally outperform a CROSS APPLY, as that executes a calculation for every record.)
Assuming your expected results are wrong, then this is how I would do it:
CREATE TABLE T1 (ID int);
CREATE TABLE T2 (ID int);
GO
INSERT INTO T1 VALUES(1),(1),(2);
INSERT INTO T2 VALUES(1),(1),(1),(2),(2);
GO
SELECT T1.ID AS OutID,
(T2.T2Count * 1.) / COUNT(T1.ID) AS OutCount --Might want a CONVERT to a smaller scale and precision decimal here
FROM T1
CROSS APPLY (SELECT T2.ID, COUNT(T2.ID) AS T2Count
FROM T2
WHERE T2.ID = T1.ID
GROUP BY T2.ID) T2
GROUP BY T1.ID,
T2.T2Count;
GO
DROP TABLE T1;
DROP TABLE T2;
You can aggregate in subqueries and then join:
select t1.id, t2.cnt * 1.0 / t1.cnt
from (select id, count(*) as cnt
from tbl1
group by id
) t1 join
(select id, count(*) as cnt
from tbl2
group by id
) t2
on t1.id = t2.id

SQL Subquery Join and Sum

I have Table 1 & 2 with common Column name ID in both.
Table 1 has duplicate entries of rows which I was able to trim using:
SELECT DISTINCT
Table 2 has duplicate numeric entries(dollarspent) for ID's which I needed and was able to sum up:
Table 1 Table 2
------------ ------------------
ID spec ID Dol1 Dol2
54 A 54 1 0
54 A 54 2 1
55 B 55 0 2
56 C 55 3 0
-I need to join these two queries into one so I get a resultant JOIN of Table 1 & Table 2 ON column ID, (a) without duplicates in Table 1 & (b) Summed $ values from Table 2
For eg:
NewTable
----------------------------------------
ID Spec Dol1 Dol2
54 A 3 1
55 B 3 2
Notes : No. of rows in Table 1 and 2 are not the same.
Thanks
Use a derived table to get the distinct values from table1 and simply join to table 2 and use aggregation.
The issue you have is you have a M:M relationship between table1 and table2. You need it to be a 1:M for the summations to be accurate. Thus we derive t1 from table1 by using a select distinct to give us the unique records in the 1:M relationship (assuming specs are same for each ID)
SELECT T1.ID, T1.Spec, Sum(T2.Dol1) as Dol1, sum(T2.Dol2) as Dol2
FROM (SELECT distinct ID, spec
FROM table1) T1
INNER JOIN table2 T2
on t2.ID = T1.ID
GROUP BY T1.ID, T1.Spec
This does assume you only want records that exist in both. Otherwise we may need to use an (LEFT, RIGHT, or FULL) outer join; depending on desired results.
I can't really see your data, but you might want to try:
SELECT DISTINCT ID
FROM TblOne
UNION ALL
SELECT DISTINCT ID, SUM(Dol)
FROM TblTwo
GROUP BY ID
Pre-aggregate table 2 and then join:
select t1.id, t1.spec, t2.dol1, t2.dol2
from (select t2.id, sum(dol1) as dol1, sum(dol2) as dol2
from table2 t2
group by t2.id
) t2 join
(select distinct t1.id, t1.spec
from table1 t1
) t1
on t1.id = t2.id;
For your data examples, you don't need to pre-aggregate table 2. This gives the correct sums -- albeit in multiple rows -- if table1 has multiple specs for a given id.

DISTINCT based on ID between Two table and SUM of the other exiting column in SQL

SELECT
SUM(amount), (DISTINCT table1.id)
FROM
table1
INNER JOIN
table2 ON table1.id = table2.id IS NULL;
Table1 id amount Table2 id product
1 40 5 10
2 364.25 2 20
3 704.5 8 30
4 404.5 3 40
5 580.5 2 20
The id is not unique or primary ------------------first i need to ignore all double entry ID from table2 then match id from table2 to table1 after that those ids will be match i need total of amount figure amount is a column name i will not calculate single the data will be more than 20000. please help me if you can
First compare match table2 id with table1 id if found any id match then those id amount need to be SUM i mean total. here match id is 2 and 3 according to table2 and then we will add this 2 and 3 id amount so result will be 364.25+704.5=1068.75 i am looking the result how can i do it using mysql.
I am trying to DISTINCT based on ID between two tables and SUM of the other existing column we have in table1. Can somebody help me how to do it?
Based on your latest comment try this
SELECT
SUM(amount)
FROM
table1
INNER JOIN
(Select Distinct ID From table2) T2 ON table1.id = T2.id
Lets leave a matter of performance beyond the topic:)
So according to this:
First compare match table2 id with table1 id if found any id match
then those id amount need to be SUM i mean total
it is possible to use correlated subquery:
select sum(t1.amount)
from table1 t1
where exists (select 1 from table2 t2 where t2.id = t1.id)
From what I understood, you need common IDs from both table and corresponding sum of amount.
SELECT
SUM(amount)
FROM
table1
WHERE
id IN (SELECT id
FROM table2);

Join table on Count

I have two tables in Access, one containing IDs (not unique) and some Name and one containing IDs (not unique) and Location. I would like to return a third table that contains only the IDs of the elements that appear more than 1 time in either Names or Location.
Table 1
ID Name
1 Max
1 Bob
2 Jack
Table 2
ID Location
1 A
2 B
Basically in this setup it should return only ID 1 because 1 appears twice in Table 1 :
ID
1
I have tried to do a JOIN on the tables and then apply a COUNT but nothing came out.
Thanks in advance!
Here is one method that I think will work in MS Access:
(select id
from table1
group by id
having count(*) > 1
) union -- note: NOT union all
(select id
from table2
group by id
having count(*) > 1
);
MS Access does not allow union/union all in the from clause. Nor does it support full outer join. Note that the union will remove duplicates.
Simple Group By and Having clause should help you
select ID
From Table1
Group by ID
having count(1)>1
union
select ID
From Table2
Group by ID
having count(1)>1
Based on your description, you do not need to join tables to find duplicate records, if your table is what you gave above, simply use:
With A
as
(
select ID,count(*) as Times From table group by ID
)
select * From A where A.Times>1
Not sure I understand what query you already tried, but this should work:
select table1.ID
from table1 inner join table2 on table1.id = table2.id
group by table1.ID
having count(*) > 1
Or if you have ID's in one table but not the other
select table1.ID
from table1 full outer join table2 on table1.id = table2.id
group by table1.ID
having count(*) > 1