Find the names that are unique using exists or not exists - sql

Table vales:
id Name
1 rahul
2 john
3 Aswin
4 jerry
5 jack
6 john
I want to print unique names, ie list with out john using Exists or Not Exists in the query.

You can do:
select name
from vales v
where not exists (select 1 from vales v1 where v1.name = v.name and v1.id <> v.id)
Note that aggregation is also a possible solution (although this does not use exists):
select name
from vales
group by name
having count(*) = 1

Related

SQL query Postgres 12

I'm doing an inner join on a table like this:
SELECT *
FROM patient p
INNER JOIN
vaccine v
ON
p.vaccine_id = v.id
The condition f.vac_1 = mv.id might not been satisfied in the case where a person have not been vaccinated. In such case, I don't want to ignore the row, but instead of displaying the vaccine name (which is the purpose of the inner join) to display an emtpy string.
How can this be done ?
Example
Table vaccinne
id
name
1
Moderna
2
Comirnaty
3
Janssen
Table patient
id
name
vaccine_id
1
john
1
2
kermit
2
3
jessica
I'm looking for a query to produce:
id
name
vaccine_id
1
john
Moderna
2
kermit
Comirnaty
3
jessica
If I understand correctly, you want a left join starting with foo:
SELECT *
FROM foo f LEFT JOIN
vac v
ON f.vac_1 = mv.id

Select data with latest date for each id

I am currently working on Microsoft Access an I am struggling to do what I want.
I have this table A:
Table A
id title name date
123 azer dfgd 1
123 afg qsd 5
123 arr poi 7
123 aur qhg 3
456 aoe aer 3
456 iuy zer 4
And I would like to get the columns id,title and name that have the latest date (highest number) for each id
With that example, the query would give
id title name date
123 arr poi 7
456 iuy zer 4
I hope you'll be able to help me.
Thanks in advance !
I would recommend a correlated subquery:
select a.*
from a
where a.date = (select max(a2.date) from a as a2 where a2.id = a.id);
For performance, you want an index on a(id, date).
With NOT EXISTS:
select t.*
from tablename t
where not exists (
select 1 from tablename
where id = t.id and date > t.date
)

TSQL - Query for multiple types in multiple rows

I have a table where each address has different types, for each type a row. How to find the addresses where for the exact types i need?
Eg.
ID TypID Street
1 1 Street 1
1 2 Street 1
2 2 Street 2
3 1 Street 3
3 2 Street 3
In the above i need to find addresses which has type 1 and 2. That query result should be adresses with id 1 and 3.
Group by the id and then count the different typeids in the having clause
select id from your_table
where typeid in (1,2)
group by id
having count(distinct typeid) = 2
You can use INTERSECT for this
select id
from tbl
where typid = 1
intersect
select id
from tbl
where typid = 2
although it won't work in mysql if that happens to be the database you're using.
This can be done with a inner join like the below
select y2.*
from <your_table> Y1
JOIN <your_table> Y2
ON Y1.ID = Y2.ID
AND Y1.Type_id in (1,2)
AND Y2.ID in (1,3)

SELECT only records which must fill two conditions

I have this table:
id type otherid
1 4 1234
2 5 1234
3 4 4321
As you can see there are 3 records, 2 of them belongs to otherid "1234" and got type of 4 and 5.
Last record belongs to otherid of "4321" and has only a type of 4.
I need to select all otherid that got only the type 4 and not the type5.
Example: after this select on that table the query shuould return only the record 3
Thanks
add1:
Please consider the TYPE can be any number from 1 up to 20.
I only need otherid that got type 4 but not type 5 ( except than that they can have any other type )
add2:
using mysql 5.1
This is kind of a workaround
SELECT * FROM (
SELECT GROUP_CONCAT('|',type,'|') type,other_id FROM table GROUP BY otherid
) t WHERE type LIKE '%|4|%' AND type NOT LIKE '%|5|%'
You could use a not exists subquery:
select distinct otherid
from YourTable as yt1
where yt1.type = 4
and not exists
(
select *
from YourTable as yt2
where yt1.otherid = yt2.otherid
and yt1.type <> yt2.type -- use this line for any difference
and yt2.type = 5 -- or this line to just exclude 5
)
Another way is by using a left join from where you exclude rows that have both type 4 and 5:
select a.*
from table1 a
left join table1 b on b.otherid = a.otherid and b.type = 5
where a.type = 4 and b.id is null

Tricky SQL - Select non-adjacent numbers

Given this data on SQL Server 2005:
SectionID Name
1 Dan
2 Dan
4 Dan
5 Dan
2 Tom
7 Tom
9 Tom
10 Tom
How would I select records where the sectionID must be +-2 or more from another section for the same name.
The result would be:
1 Dan
4 Dan
2 Tom
7 Tom
9 Tom
Thanks for reading!
SELECT *
FROM mytable a
WHERE NOT EXISTS
(SELECT *
FROM mytable b
WHERE a.Name = b.Name
AND a.SectionID = b.SectionID + 1)
Here's LEFT JOIN variant of Anthony's answer (removes consecutive id's from the results)
SELECT a.*
FROM mytable a
LEFT JOIN mytable b ON a.Name = b.Name AND a.SectionID = b.SectionID + 1
WHERE b.SectionID IS NULL
EDIT: Since there is another interpretation of the question (simply getting results where id's are more than 1 number apart) here is another attempt at an answer:
WITH alternate AS (
SELECT sectionid,
name,
EXISTS(SELECT a.sectionid
FROM mytable b
WHERE a.name = b.name AND
(a.sectionid = b.sectionid-1 or a.sectionid = b.sectionid+1)) as has_neighbour,
row_number() OVER (PARTITION by a.name ORDER BY a.name, a.sectionid) as row_no
FROM mytable a
)
SELECT sectionid, name
FROM alternate
WHERE row_no % 2 = 1 OR NOT(has_neighbour)
ORDER BY name, sectionid;
gives:
sectionid | name
-----------+------
1 | Dan
4 | Dan
2 | Tom
7 | Tom
9 | Tom
Logic: if a record has neighbors with same name and id+/-1 then every odd row is taken, if it has no such neighbors then it gets the row regardless if it is even or odd.
As stated in the comment the condition is ambiguous - on start of each new sequence you might start with odd or even rows and the criteria will still be satisfied with different results (even with different number of results).