How to select rows with condition? sql, select sentence - sql

I have table like this:
NAME IDENTIFICATIONR SCORE
JOHN DB 10
JOHN IT NULL
KAL DB 9
HENRY KK 3
KAL DB 10
HENRY IP 9
ALI IG 10
ALI PA 9
And with select sentence I want that my result would be like only those names whose scores are 9 or above. So basically it means, that, for exaple, Henry cannot be selected, because he has score under the value of 9 in one line , but in the other he has the score of 3 (null values also should be emitted).
My newtable should look like this:
NAME
KAL
ALI
I'm using a sas program. THANK YOU!!

The COUNT of names will be <> COUNT of scores if there is a missing score. Requesting equality in the having clause will ensure no person with a missing score is in your result set.
proc sql;
create table want as
select distinct name from have
group by name
having count(name) = count(score) and min(score) >= 9;

here the solution
select name
from table name where score >= 9
and score <> NULL;

Select NAME from YOUR_TABLE_NAME name where SCORE > 9 and score is not null

You can do aggregation :
select name
from table t
group by name
having sum(case when (score < 9 or score is null) then 1 else 0 end) = 0;
If you want full rows then you can use not exists :
select t.*
from table t
where not exists (select 1
from table t1
where t1.name = t.name and (t1.score < 9 or t1.score is null)
);

You seem to be treated NULL scores as a value less than 9. You can also just use coalesce() with min():
select name
from have
group by name
having min(coalesce(score, 0)) >= 9;
Note that select distinct is almost never useful with group by -- and SAS proc sql probably does not optimize it well.

Related

Sql Query: How to Base on the row name to display

I have the table data as listed on below:
name | score
andy | 1
leon | 2
aaron | 3
I want to list out as below, even no jacky's data, but list his name and score set to 0
aaron 3
andy 2
jacky 0
leon 2
You didn't specify your DBMS, but the following is 100% standard ANSI SQL:
select v.name, coalesce(t.score, 0) as score
from (
values ('andy'),('leon'),('aaron'),('jacky')
) as v(name)
left join your_table t on t.name = v.name;
The values clause builds up a "virtual table" that contains the names you are interested in. Then this is used in a left join so that all names from the virtual table are returned plus the existing scores from your (unnamed table). For non-existing scores, NULL is returned which is turned to 0 using coalesce()
If you only want to specify the missing names, you can use a UNION in the virtual table:
select v.name, coalesce(t.score, 0) as score
from (
select t1.name
from your_table t1
union
select *
from ( values ('jacky')) as x
) as v(name)
left join your_table t on t.name = v.name;
fixed the query, could list out the data, but still missing jacky, only could list out as shown on below, the DBMS. In SQL is SQL2008.
data
name score scoredate
andy 1 2021-08-10 01:23:16
leon 2 2021-08-10 03:25:16
aaron 3 2021-08-10 06:25:16
andy 4 2021-08-10 11:25:16
leon 5 2021-08-10 13:25:16
result set
name | score
aaron | 1
andy | 5
leon | 7
select v.name as Name,
coalesce(sum(t.score),0) as Score
from (
values ('aaron'), ('andy'), ('jacky'), ('leon')
) as v(name)
left join Score t on t.name=v.name
where scoredate>='2021-08-10 00:00:00'
and scoredate<='2021-08-10 23:59:59'
group by v.name
order by v.name asc
Your question lacks a bunch of information, such as where "Jacky"s name comes from. If you have a list of names that you know are not in the table, just use union all:
select name, score
from t
union all
select 'Jacky', 0;

Count combined with select distinct

actually i try to find a way to select all distinct private message from a table and also got the count of each in 1 sql query
the actual table have column with the id of the member and also a column
with the actual view state of the message when the message state = 0 it mean
not read
example of data in table
roger 0
paul 1
roger 0
paul 0
mike 0
mike 0
mike 0
then the result i want is
roger 2
paul 1
mike 3
any help will be apreciated thanks
Are you looking for this?
SELECT member_id, COUNT(*) AS count
FROM messages
WHERE state = 0
GROUP BY member_id
Here is a dbfiddle demo
I need also to select all field from another table that will match the member_id is that possible in 1 query
Sure, JOIN away
SELECT m.*, t.*
FROM (
SELECT member_id, COUNT(*) AS count
FROM messages
WHERE state = 0
GROUP BY member_id
) m JOIN other_table t
ON m.member_id = t.member_id

How to select id's that have rows for all values from a set

I want to select all Id from a table that have rows for both programs 'basketball' and 'football'
Given a table like this:
Id program
1 basketball
2 football
3 basketball
2 basketball
1 football
4 football
5 basketball
How can I get a result like this:
id
1
2
Since you want to return the id's that have both values football and basketball, you can use the following to get the result:
select id
from yt
where program in ('basketball', 'football')
group by id
having count(distinct program) = 2;
See SQL Fiddle with Demo.
Since can also be done by joining on your table multiple times:
select t1.id
from yt t1
inner join yt t2
on t1.id = t2.id
where t1.program = 'basketball'
and t2.program = 'football';
See SQL Fiddle with Demo
I think aggregation is the most generalizable approach for this:
select id
from table
group by id
having sum(case when program = 'Football' then 1 else 0 end) > 0 and
sum(case when program = 'Basketball' then 1 else 0 end) > 0
The sum() statement are counting the number of rows that have "football" and "basketball" respectively. When present, the number is greater than 0.
You can do this with IN or OR syntax:
SELECT id
FROM table
WHERE program = 'basketball'
OR program = 'football';
If you want to only get the first two results, add LIMIT 2 to the end.
By the way, it's really bad practice to have a table without a primary key, there is no way to index this table so performance would be very bad.

SQL - Removing Duplicate without 'hard' coding?

Heres my scenario.
I have a table with 3 rows I want to return within a stored procedure, rows are email, name and id. id must = 3 or 4 and email must only be per user as some have multiple entries.
I have a Select statement as follows
SELECT
DISTINCT email,
name,
id
from table
where
id = 3
or id = 4
Ok fairly simple but there are some users whose have entries that are both 3 and 4 so they appear twice, if they appear twice I want only those with ids of 4 remaining. I'll give another example below as its hard to explain.
Table -
Email Name Id
jimmy#domain.com jimmy 4
brian#domain.com brian 4
kevin#domain.com kevin 3
jimmy#domain.com jimmy 3
So in the above scenario I would want to ignore the jimmy with the id of 3, any way of doing this without hard coding?
Thanks
SELECT
email,
name,
max(id)
from table
where
id in( 3, 4 )
group by email, name
Is this what you want to achieve?
SELECT Email, Name, MAX(Id) FROM Table WHERE Id IN (3, 4) GROUP BY Email;
Sometimes using Having Count(*) > 1 may be useful to find duplicated records.
select * from table group by Email having count(*) > 1
or
select * from table group by Email having count(*) > 1 and id > 3.
The solution provided before with the select MAX(ID) from table sounds good for this case.
This maybe an alternative solution.
What RDMS are you using? This will return only one "Jimmy", using RANK():
SELECT A.email, A.name,A.id
FROM SO_Table A
INNER JOIN(
SELECT
email, name,id,RANK() OVER (Partition BY name ORDER BY ID DESC) AS COUNTER
FROM SO_Table B
) X ON X.ID = A.ID AND X.NAME = A.NAME
WHERE X.COUNTER = 1
Returns:
email name id
------------------------------
jimmy#domain.com jimmy 4
brian#domain.com brian 4
kevin#domain.com kevin 3

write a query to identify discrepancy

I have a table with Student ID's and Student Names. There has been issues with assigning unique Student Id's to students and Hence I want to find the duplicates
Here is the sample Table:
Student ID Student Name
1 Jack
1 John
1 Bill
2 Amanda
2 Molly
3 Ron
4 Matt
5 James
6 Kathy
6 Will
Here I want a third column "Duplicate_Count" to display count of duplicate records.
For e.g. "Duplicate_Count" would display "3" for Student ID = 1 and so on. How can I do this?
Thanks in advance
Select StudentId, Count(*) DupCount
From Table
Group By StudentId
Having Count(*) > 1
Order By Count(*) desc,
Select
aa.StudentId, aa.StudentName, bb.DupCount
from
Table as aa
join
(
Select StudentId, Count(*) as DupCount from Table group by StudentId
) as bb
on aa.StudentId = bb.StudentId
The virtual table gives the count for each StudentId, this is joined back to the original table to add the count to each student record.
If you want to add a column to the table to hold dupcount, this query can be used in an update statement to update that column in the table
This should work:
update mytable
set duplicate_count = (select count(*) from mytable t where t.id = mytable.id)
UPDATE:
As mentioned by #HansUp, adding a new column with the duplicate count probably doesn't make sense, but that really depends on what the OP originally thought of using it for. I'm leaving the answer in case it is of help for someone else.