Merge two sql queries select and count - sql

Hello I have two sql queries and i would like to merge or combine them
Query1:
Select TableA.Name, TableB.Date
from TableA, TableB
where ID = ID_used;
Query2:
SELECT count(Date)
FROM (SELECT DISTINCT Date
FROM TableA, TableB
group by Date;
I tried:
Select TableA.Name, TableB.Date
from TableA, TableB
where ID=ID_used inner join (SELECT count(Date)
FROM (SELECT DISTINCT Date
FROM TableA, TableB
group by Date)
But it gives syntax error in union query.
The result what I need: Name, count result.
Any Idea?
Test datas:
TableA
---------------------
Name ID
---------------------
John 1001
Peter 1002
TableB
-----------------------
Date ID_used
-----------------------
2015.05.01.AM 1001
2015.05.01.AM 1001
2015.05.01.AM 1002
2015.05.01.PM 1001
2015.05.01.PM 1001
2015.05.01.PM 1002
2015.05.01.PM 1002
2015.05.02.PM 1002
Results have to be:
John 2
Peter 3

As I understand it what you need is something like this:
(Although I am not sure because you didn't add test data and expected results)
Select t1.Name,t2.Date,
(select count(date)
from (select distinct date
FROM TableA,TableB
GROUP BY Date)) as datecount
from TableA t1
join TableB t2
on t1.ID = t2.ID_used
UPDATE: I think this is what you are looking for: SQLFIDDLE
select t1.id, t1.name, count(t2.Date)
FROM TableA t1
JOIN (
SELECT Distinct id_used,Date
FROM TableB) t2
ON t1.id = t2.id_used
GROUP by t1.id
EDIT: I tried this in ms access 2010:
NOTE: I couldn't use the keyword Date as a column name so changed to mydate
select t1.id, t1.name, count(t2.mydate) as datecount
FROM TableA t1,
(SELECT Distinct id_used,mydate
FROM TableB) t2
WHERE t1.id = t2.id_used
GROUP by t1.id,t1.name
That worked but I don't recommend using joins without the join or on keywords so here is one that is better readable and also works:
select t1.id, t1.name, count(t2.mydate) as datecount
FROM TableA t1
INNER JOIN (
SELECT Distinct id_used,mydate
FROM TableB) t2
ON t1.id = t2.id_used
GROUP by t1.id,t1.name

This returns the count of distinct dates from tableB for each Name in tableA:
Select a.Name, COUNT(DISTINCT b.Date)
from TableA AS a JOIN TableB AS b
ON ID=ID_used
group by a.Name

Use tablename before the column name
Select TableA.Name,TableB.Date from TableA, TableB where ID=ID_used;

Related

Get exclusive users in each table

I have 4 tables as shown below
For each table I want the count of users that are present exclusively in that table (not present in other tables). The result should look something likes this
I have one way of getting desired result as shown below:
First Column:
SELECT COUNT(DISTINCT A.id) table1_only
FROM table1 A
LEFT JOIN (SELECT DISTINCT id
FROM table2
UNION
SELECT DISTINCT id
FROM table3
UNION
SELECT DISTINCT id
FROM table4) B
ON A.id = B.id
WHERE B.id IS NULL
Second Column:
SELECT COUNT(DISTINCT A.id) table2_only
FROM table2 A
LEFT JOIN (SELECT DISTINCT id
FROM table1
UNION
SELECT DISTINCT id
FROM table3
UNION
SELECT DISTINCT id
FROM table4) B
ON A.id = B.id
WHERE B.id IS NULL
Third Column:
SELECT COUNT(DISTINCT A.id) table3_only
FROM table3 A
LEFT JOIN (SELECT DISTINCT id
FROM table1
UNION
SELECT DISTINCT id
FROM table2
UNION
SELECT DISTINCT id
FROM table4) B
ON A.id = B.id
WHERE B.id IS NULL
Fourth Column:
SELECT COUNT(DISTINCT A.id) table4_only
FROM table4 A
LEFT JOIN (SELECT DISTINCT id
FROM table1
UNION
SELECT DISTINCT id
FROM table2
UNION
SELECT DISTINCT id
FROM table3) B
ON A.id = B.id
WHERE B.id IS NULL
But I wanted to know if there is any efficient and scalable way to get same result. Just for 4 tables the amount of code is too much.
Any ways of optimizing this task will be really helpful.
Sample fiddle. (This fiddle is for mysql, I am looking for a generic SQL based approach than any db specific approach)
P.S.:
There is no complusion on the result needs to be in column wise. It can be row wise as well, as shown below:
I would approach this by combining the data from all tables. Then aggregate and filter:
select which, count(*) as num_in_table_only
from (select id, min(which) as which, count(*) as cnt
from ((select id, 1 as which from table1) union all
(select id, 2 as which from table2) union all
(select id, 3 as which from table3) union all
(select id, 4 as which from table4)
) t
group by id
) i
where cnt = 1
group by which
Note: In your sample data, the ids are unique in each table. This solution assumes that is true, but can easily be tweaked to handle duplicates within a table.

SQL Query, how to get data from two tables

Table 1:
ID (unqiue), Name, Address
Table 2:
RecordId, ID (key of table 1), Child name
In one query, I want to retrieve all rows of Table 1 with one additional column which will be the count of all record in table 2 from ID (that is number of children for each ID in table 1). Can't figure out how to format a query to retrieve this data.
Simply Join and apply count
select T1.*, COUNT(T2.RECORDID)AS T2COUNT from Table1 T1
INNER JOIN TABLE2 T2 ON T1.ID= T2.ID
--LEFT JOIN TABLE2 T2 ON T1.ID= T2.ID --if you need 0 child records (from commets by #Cha)
GROUP BY T1.ID , T1.Name, T1.Address
The correct way of doing this will be with a OUTER JOIN:
SELECT a.ID, a.Name, a.Address, b.cnt
FROM Table1 a
LEFT OUTER JOIN
(SELECT ID, count(*) cnt from Table2 GROUP BY ID) b
ON a.ID = b.ID
The incorrect way will be with a help of a correlated sub-query:
SELECT a.ID, a.Name, a.Address,
(SELECT count(*) FROM Table2 b WHERE b.ID = a.ID) as cnt
FROM Table1 a
Here is a discussion about correlated subqueries vs OUTER JOINs, if you are interested
Group by table1 fields and count total records in table2:
here T1 alias of table1 and T2 alias of table2.
select T1.ID, T1.Name, T1.Address, count(T2.ID) as total_records
from table1 as T1
left outer join table2 as T2 on T2.ID=T1.ID
group by T1.ID, T1.Name, T1.Address

Get the latest date record

I have two tables in my SQL Database.
ID CDATE
1 12/04/14
2 14/05/14
3 20/01/14
ID NAME
1 A
2 A
3 B
But I need the output as below.
NAME CDATE
A 14/05/14
B 20/01/14
Do you have any suggestions for me ?
SELECT MAX(t1.CDATE), t2.NAME FROM table1 t1 LEFT JOIN table2 t2 ON t1.ID = t2.ID GROUP BY t2.NAME ORDER BY t1.CDATE DESC
Try this:
SELECT t1.cdate, t2.name
FROM table1 t1
LEFT JOIN table2 t2 ON t1.id=t2.id
ORDER BY t1.cdate DESC;
Edit:
SELECT s1.cdate,
t2.name
FROM table2 t2
LEFT JOIN
(SELECT ID, MAX(cdate) cdate FROM table1 GROUP BY ID
) s1
ON s1.id=t2.id
ORDER BY s1.cdate DESC;
EDIT: Since you changed the question...
SELECT TOP 2 n.NAME, d, CDATE
FROM Dates d
LEFT JOIN Names n ON d.ID=n.ID
ORDER BY d.CDATE;
To Make table you need to create relation between this table
http://www.w3schools.com/sql/sql_foreignkey.asp
and then to get data from two table
http://www.w3schools.com/sql/sql_join.asp

Select from table not in another table

I have two tables, each with the following fields: IDnumber, SectionNumber, Date. There is overlapping information in the two tables.
How do I select only rows that do NOT overlap (ie. in one table but not the other)?
You can use a NOT IN in your WHERE clause.
SELECT IDnumber, SectionNumber, Date
FROM table1
WHERE IDnumber NOT IN (SELECT IDnumber FROM table2)
OR NOT EXISTS
SELECT IDnumber, SectionNumber, Date
FROM table1 t1
WHERE NOT EXISTS (SELECT IDnumber FROM table2 t2 WHERE t1.IDnumber = t2.IDnumber)
Which DBMS?
If SQL Server, then it's almost what you wrote in the title...
SELECT *
FROM Table1
WHERE IDnumber NOT IN (SELECT IDnumber FROM Table2)
If you want to compare multiple columns, you need an outer join:
select table1.*
from table1 left outer join
table2
on table1.id = table2.id and
table1.SectionNumber = table2.SectionNumber and
table1.date = table2.date
where table2.id is null
In the case where you might have many matches between the tables, then the join can be inefficient. Assuming you only want those three fields, you can use a trick that avoids the join:
select id, SectionNumber, date
from ((select 0 as IsTable2, id, SectionNumber, date
from table1
) union all
(select 1 as IsTable2, id, SectionNumber, date
from table2
)
) t
group by id, SectionNumber, date
having max(isTable2) = 0
SELECT *
FROM Table1 t1 left join Table2 t2
on t1.id=t2.id
where t2.id is null

retrieving rows with max date

I have two tables like this:
Table1 (Number column is unique)
Number | date
1234 2008-10-06 17:11:00
5678 2005-10-19 16:20:00
9023 2005-12-09 16:20:00
4243 2009-01-06 17:11:00
5234 2009-01-14 17:11:00
Table 2
Number | code
1234 A1
1234 B1
5678 A1
9023 A1
4243 C1
5234 C1
I am trying to retrieve data from these two tables so that I get only one row for each code in Table 2 that is the most recent (from table 1).
Based on this example, my result would be:
1234 A1 (because thats the one with latest date)
1234 B1 (because thats the one with latest date)
5234 C1 (because thats the one with latest date)
Select Distinct T1.number, T2.code
From Table2 T2
Join Table1 T1
On T1.Number = T2.Number
And T1.date =
(Select Max(Date) From Table1
Where Number = T2.Number)
EDIT: to fix issue noted in comment:
Select Z.Number, Z.Code
From (Select A.number, A.code, B.date
From Table2 A Join Table1 B
On B.Number = A.Number) Z
Where Z.Date =
(Select Max(Date)
From Table2 A Join Table1 B
On B.Number = A.Number
Where code = Z.Code)
Analytic function solution. This is for Oracle; if you're using another RDBMS it may not work. If there are multiple rows with the same date for a given code, this will arbitrarily select one.
SELECT number, code FROM (
SELECT t1.number,
t1.code,
row_number() OVER ( PARTITION BY t1.code ORDER BY t2.date DESC ) date_sort_key
FROM t1, t2
WHERE t2.number = t1.number
)
WHERE date_sort_key = 1
Substituting rank() for row_number() would make it report multiple entries where there is a duplicate date.
Here is a version of Dave's answer that works on SQL Server
SELECT number, code FROM (
SELECT Table2.number,
Table2.code,
row_number() OVER ( PARTITION BY table2.code ORDER BY table1.date DESC ) date_sort_key
FROM table1, Table2
WHERE Table2.number = table1.number
) a
WHERE date_sort_key = 1
This works for SQL SERVER
CREATE table Table1 (number int, date datetime)
INSERT Table1 VALUES (1234, '2008-10-06 17:11:00')
,(5678, '2005-10-19 16:20:00')
,(9023, '2005-12-09 16:20:00')
,(4243, '2009-01-06 17:11:00')
,(5234, '2009-01-14 17:11:00')
CREATE table Table2 (number int, code varchar(2))
INSERT Table2 VALUES (1234, 'A1 ')
,(1234, 'B1')
,(5678, 'A1')
,(9023, 'A1')
,(4243, 'C1')
,(5234, 'C1')
SELECT DISTINCT
a.number
,a.code
FROM Table2 a
INNER JOIN Table1 b ON a.number = b.number
INNER JOIN (
SELECT
t2.code
,MAX(t1.date) as date
FROM Table2 t2
INNER JOIN Table1 t1
ON t1.Number = t2.Number
GROUP BY t2.code
) c ON b.date = c.date