sql combining count with other fields - sql

Consider a scenario:
id name info done
-----------------------
1 abc x 0
2 abc y 1 <-- I have this id
3 pqr g 1
4 pqr h 0
5 pqr i 1 <-- I have this id
I have id for the last entry of every name.
The result I'm expecting consists of 2 things:
info for last entry of the name
number of done [having value 1] for that name
(1) can be easily achieved by select info from table where id = myid
But how can (2) be achieved in the same query? Can it be achieved in the same query?
Something like
select info, count(done) from table where id = myid group by name where ......

This is a bit complicated, but can be done using conditional aggregation:
select max(case when t.id = myid then info end), sum(done)
from table t
where t.name = (select name from table t2 where t2.id = myid);
The key is getting all the rows for the given name.
If you had multiple columns, then a correlated subquery might be the way to go:
select t.*,
(select sum(t2.done) from table t2 where t2.name = t.name) as numdone
from table t
where t.id = myid;

You could join the table back to itself on name to get this.
SELECT t1.myid, t1.info, sum(t2.done) as number_of_done
FROM table t1 INNER JOIN table t2 on t1.name = t2.name
WHERE t1.id = myid
GROUP BY t1.myid, t1.info

Considering done is either 1 or 0 you could just get the sum and display that.
select info, sum(done)
from table where id = mid
group by info
EDIT:
select info, s
from table
inner join (
select name, sum(done) as s
from table
group by name
) as zzz on zzz.name = table.name
where id = myid

If you want it to display with more detailed data, use a windowing function:
select info, count(done) over (partition by name) ...

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

How to compare two tables in Hive based on counts

I have below hive tables
Table_1
ID
1
1
2
Table_2
ID
1
2
2
I am comparing two tables based on count of ID in both tables, I need the output like below
ID
1 - 2records in table 1 and 1 record in Table 2
2 - one record in Table 1 and 2 records in table 2
Table_1 is parent table
i am using below query
select count(*),ID from Table_1 group by ID;
select count(*),ID from Table_2 group by ID;
Just do a full outer join on your queries with the on condition as X.id = Y.id, and then select * from the resultant table checking for nulls on either side.
Select id, concat(cnt1, " entries in table 1, ",cnt2, "entries in table 2") from (select * from (select count(*) as cnt1, id from table1 group by id) X full outer join (select count(*) as cnt2, id from table2 group by id)
on X.id=Y.id
)
Try This. You may use a case statement to check if it should be record / records etc.
SELECT m.id,
CONCAT (COALESCE(a.ct, 0), ' record in table 1, ', COALESCE(b.ct, 0),
' record in table 2')
FROM (SELECT id
FROM table_1
UNION
SELECT id
FROM table_2) m
LEFT JOIN (SELECT Count(*) AS ct,
id
FROM table_1
GROUP BY id) a
ON m.id = a.id
LEFT JOIN (SELECT Count(*) AS ct,
id
FROM table_2
GROUP BY id) b
ON m.id = b.id;
You could use this Python program to do a full comparison of 2 Hive tables:
https://github.com/bolcom/hive_compared_bq
If you want a quick comparison just based on counts, then pass the "--just-count" option (you can also specify the group by column with "--group-by-column").
The script also allows you to visually see all the differences on all rows and all columns if you want a complete validation.

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

Query a table that have 2 cols with multiple criteria

I have a table with the following structure and Example data:
Now I want to query the records that have value equals to # and #.
For example according to the above image, It should returns 1 and 2
id
-----
1
2
Also if the parameters were #, # and $ It should give us 1. Because only the records with id 1 have all the given values.
id
-----
1
You can use a group by and having to get the distinct Id's that contain a distinct count of the number of items you're looking for
SELECT Id
FROM Table
WHERE Value IN ('#','$')
GROUP BY Id
HAVING COUNT(DISTINCT Value) = 2
SELECT Id
FROM Table
WHERE Value IN ('#','$','#')
GROUP BY Id
HAVING COUNT(DISTINCT Value) = 3
SQL Fiddle you can use this link to test
There's several ways to do this.
The subquery method:
SELECT DISTINCT Id
FROM Table
WHERE Id IN (SELECT Id FROM Table WHERE Value = '#')
AND Id IN (SELECT Id FROM Table WHERE Value = '#');
The correlated subquery method:
SELECT DISTINCT t.Id
FROM Table t
WHERE EXISTS (SELECT 1 FROM Table a WHERE a.Id = t.Id and a.Value = '#')
AND EXISTS (SELECT 1 FROM Table b WHERE b.Id = t.Id and b.Value = '#');
And the INTERSECT method:
SELECT Id FROM Table WHERE Value = '#'
INTERSECT
SELECT Id FROM Table WHERE Value = '#';
Best performance will depend on RDBMS vendor, size of table, and indexes. Not all RDBMS vendors support all methods.
Maybe a multiple self join like this?
select
distinct t1.id
from
table t1
join table t2 on (t1.id=t2.id)
join table t3 on (t1.id=t3.id)
...
where
t1.value='#' and
t2.value='#' and
t3.value='$' and
...

SQL Join and Count

I want to join two tables and get data against an ID from the first table and count a column record from the second table against the same ID. I want a single query which gives me that output.
Following is a use-case/example for your problem and a proposed solution:
You have two tables User and User_Friends which store user-data and contact-information respectively.
And you want to display the name and number of contacts a user has.
Table User:
id Name
0 A
1 B
2 C
3 D
Table User_Friends:
id friend_id
0 1
0 2
0 3
1 2
1 3
Output:
Name Count(*)
A 3
B 2
C 0
D 0
//Display the Name, number of friends
SELECT Name, count(*)
FROM User, User_Friends
WHERE User.id = User_Friends.id
GROUP BY User_Friends.id
I think you're asking about a query like this:
select t1.id, count(t2.id)
from table1 as t1
left outer join table2 as t2
on t2.table1_id = t1.id
group by t1.id;
select
ID,
(select count(*) from table2 where ID=p.ID) as [count]
from table1 p