SQL: select values in table A which are not in table B (and the other way around) - sql

I have a hypothetical Census information by areas (Districts) collected in two different years:
Year 1 Table
District | Name
----------------
1 | Paul
1 | John
2 | Max
2 | Aaron
3 | Michael
Year 2 Table
District | Name
1 | Paul
1 | John
1 | Michael
3 | Michael
I'd like two queries:
Query 1: List new people by District. Should return Michael in District 1
Query 2: List missed people by District. Should return Max and Aaron in District 2

I would do this using union all and aggregation. The following query returns the name/district combinations that appear only in one year, along with the specific year:
select district, name, min(yyyy)
from ((select 1 as yyyy, district, name from table1) union all
(select 2, district, name from table2)
) tt
group by district, name
having count(distinct yyyy) = 1;

Query 1 : List new people by District. Should return Michael in District 1
SELECT Name, District
FROM year2
WHERE (Name NOT IN
(SELECT Name
FROM year1
WHERE (District = year2.District)))
GROUP BY Name, District
Query 2: List missed people by District. Should return Max and Aaron in District 2
SELECT Name, District
FROM year1
WHERE (Name NOT IN
(SELECT Name
FROM year2
WHERE (District = District)))
GROUP BY Name, District
If further you need combined result just use union all

Related

count different column values after grouping by

Consider this table:
id name department email
1 Alex IT blah#gmail.com
1 Alex IT blah#gmail.com
2 Jay HR jay#gmail.com
2 Jay Marketing zou#gmail.com
If I group byid,name and count I get:
id name count(*)
1 Alex 2
2 Jay 2
With this query:
select id,name,count(*) from tb group by id,name;
However I would like to count only records that diverge from department,email, so as to have:
id name count(*)
1 Alex 0
2 Jay 1
This time the count for the first group 1,Alex is 0 because department,email have the same values (duplicated) , on the other hand 2,Jay is one because department,email has one different value.
If you meant "two different values" for "Jay", you can use distinct:
select id,name,count(*) from (SELECT distinct * FROM tb) group by id,name;
You can use count(*) - 1 to get similar results in your question.

SQL query all register but select only one of one column [duplicate]

This question already has answers here:
Get top 1 row of each group
(19 answers)
Closed 1 year ago.
Assume that I have one table looking like this:
ID
ClientID
Name
Country
1
JX100
John
Canada
2
JX100
John
Japan
3
JX690
Rob
EUA
4
PX301
Alice
France
And My query:
SELECT DISTINCT ClientID,Name,Country FROM CLIENTS
OUTPUT:
ClientID
Name
Country
JX100
John
Canada
JX100
John
Japan
JX690
Rob
EUA
PX301
Alice
France
I want to take that:
DESIRED:
ClientID
Name
Country
JX100
John
Canada
JX690
Rob
EUA
PX301
Alice
France
TL;DR
I just want to select one country for all Clients, I don't want to get repeated rows.
You can use row_number()over() with common table expression like below:
with cte as (
SELECT DISTINCT ClientID,Name,Country,row_number()over(partition by ClientID ,Name order by Country) rownumber FROM CLIENTS)
select * from cte where rownumber=1
Row_number()over(partition by ClientID ,Name order by Country) will generate a sequence for contries starting from 1 against each clientid and name. So when you will select rownumber=1 this query will select one country for a single clientid,name combination.

how to SQL query with conditioned distinct

Simple Database:
street | age
1st st | 2
2nd st | 3
3rd st | 4
3rd st | 2
I'd like to build a query that'll return the DISTINCT street names, but only for those households where no one is over 3.
so that result would be:
street | age
1st st | 2
2nd st | 3
How do I do that? I know of DISTINCT, but now how to conditionalize it for all the records that match the DISTINCT
Suppose the name of the table is 'tab'. You can then try:
select distinct street from tab where street not in (select street from tab where age>3);
I have created a sql fiddle where you can view the result:
http://sqlfiddle.com/#!9/2c513d/2
Distinct street names for households where no one is over 3:
SELECT street
FROM table
GROUP BY street
HAVING COUNT(1) <= 3
SELECT DISTINCT street
FROM table
WHERE NOT(age>3)
USE GROUP BY
Select Street
from yourtable
group by street
Having sum(age)<=3
Another way this could be achived with a use of NOT EXISTS
SELECT *
FROM yourtable a
WHERE NOT EXISTS
(SELECT street
FROM yourtable b
WHERE age > 3
AND a.street = b.street)

How to select only details of min value only in SQL?

I could get the minimum percentage of two values, but I need only the name, and ID in the select.
ID NAME CITY ONE TWO
--------------------------------------------------
2 Morales Los Angeles 40 10
1 John New York 60 20
4 Mary San Diego 10 10
I need to get the min value of one/two, and to only appear this as a result:
ID NAME
---------
4 Mary
Select ID, NAME
from MYTABLE
where least(ONE,TWO) = (select min(least(ONE,TWO)) from MYTABLE);
If you don't want Morales, then you can do this :
Select ID, NAME
from MYTABLE
where id =
(select id from
(select id from MYTABLE order by least(ONE,TWO), ONE*TWO)
where rownum <= 1);

SELECT Top 1 ID, DISTINCT Field

I have a table sample table as follows:
ID | City
--------------
1 | New York
2 | San Francisco
3 | New York
4 | Los Angeles
5 | Atlanta
I would like to select the distinct City AND the TOP ID for each. E.g., conceptually I would like to do the following
SELECT TOP 1 ID, DISTINCT City
FROM Cities
Should give me:
ID | City
--------------
1 | New York
2 | San Francisco
4 | Los Angeles
5 | Atlanta
Because New York appears twice, it's taken the first ID 1 in this instance.
But I get the error:
Column 'Cities.ID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Try this way:
SELECT min(ID), City
FROM Cities
Group by City
MIN function is used for choose one of the ID from two New York cities.
You need to have your city in a GROUP BY
SELECT MIN(ID), City
FROM Cities
GROUP BY City
More general solution is to use row_number in order to get other details of table:
select * from
(select *, row_number() over(partition by City order by ID) as rn from Cities)
where rn = 1
But for this particular table just grouping will do the work:
select City, Min(ID) as ID
from Cities
group by City
If you have a complex scenario where Group By cannot use, You could use Row_Number() function with Common Table Expression.
;WITH CTE AS
(
SELECT ID, City, ROW_NUMBER() OVER (PARTITION BY City ORDER BY Id) rn
FROM YourTable
)
SELECT Id, City
FROM CTE
WHERE rn = 1