I have a database view which gives me following result:
From this I want to select all the users which have groups 00113 and 00221.. so on. That is the users which have access to all those groups and not any one group.
I am a fan of using group by and having for these types of queries. One method for finding things in a list:
select id
from table
where group_number in ('00113', '00221')
group by id
having count(distinct group_number = '00113') = 2;
A more general method that allows you to get members of one list, excluding members from another:
select id
from table
group by id
having sum(case when group_number = '00113' then 1 else 0 end) > 0 and
sum(case when group_number = '00221' then 1 else 0 end) > 0;
select * from table
where ID not IN
( select distinct ID from Table
where GROUP_NUMBER not IN ('00221','00113')
) group by ID having count (distinct GROUP_NUMBER) = 2;
As ruudvan pointed out this can be directly done with only one IN
select * from table
where ID IN ('00221','00113')
group by ID having count (distinct GROUP_NUMBER) = 2;
The inner query gives the list of all IDs whose group_number is not present in the given list.
So you need to select all the IDs not present in the IDs given by inner query
Your intent is a bit ambiguous but if what you want is to return the user that for example have access to the groups 00113 and 00221 and no other groups then this would work.
One way to do this would be to use a conditional aggregation in the having clause of the group by:
select id from your_table
group by id
having sum(case
when group_number = '00113' then 1
when group_number = '00221' then 1
else -1 end
) = 2
Sample SQL Fiddle
select first_name, last_name, id from mytable where group_number = '00113'
INTERSECT
select first_name, last_name, id from mytable where group_number = '00221'
Related
I'm using group by and I use count distinct to count unique ids but it only counts unique ids for each group. I want to count if that id was not count in another group.
with data as (
select *, count() over (partition by id1) as id1cnt
from T
)
select id2, count(case when id1cnt = 1 then 1 end) cnt
from data
group by id2
I can't correctly write a query.
I need to select a person who has only one value in the column. For example,
select * (
select PersonID, sum(TotalAmount)
from Table1
group by PersonID
HAVING sum(TotalAmount) = 0 )
where Group = A
It means that I would select all customers that belong to ONLY 'A' group...
Could someone help me?
If you want the persons with only one value, then having count(*) = 1 comes to mind:
select personid
from table1
group by personid
having count(*) = 1;
I have a table with duplicate records say example multiple records with same account number. like this
Now I want to select only those records id which satisfies below condition priority wise:
Select the account number for which the prim_cust is X
If X is null than select account number which is having dept_id not null.
Both null than we should select the min(id).
Here we will have to group the account number and perform the above conditions.
I just want single record with unique account number with above conditions satisfied.
The condition should follow the priority
I think you have a prioritization query, where you want one row per acct_nbr subject to your various rules.
For this type of problem, row_number() is quite handy:
select t.*
from (select t.*,
row_number() over (partition by acct_nbr
order by (case when prim_cust = 'X' then 1 else 2 end),
(case when dept_id is not null then 1 else 2 end),
id
) as seqnum
from t
) t
where seqnum = 1;
I have a table that contain UserID's and Departments. UserID's can belong to several departments so their combo makes it unique.
However I have been trying to query trying to find where the UserID belongs to either one of two departments (hr or customer).
SELECT UserId, Dept, COUNT(*) Total
FROM MyTable
GROUP BY UserID
HAVING COUNT(*) = 1
However this still brings back duplicates if a UserId has both departments I guess because the combo makes it a unique record.
What I get back is this
UserID | Department | Total
1 hr 1
2 customer 1
3 customer 1
1 customer 1
3 hr 1
But what I am trying to get back is this
UserID | Department | Total
2 customer 1
Where any instances of UserId belonging to both departments are not included only if they belong to one or the other.
This should do the job
select t1.UserId, Dept, t2.Total
FROM MyTable t1
INNER JOIN
(
SELECT UserId, COUNT(*) Total
FROM Table1
GROUP BY UserID
HAVING COUNT(*) = 1
) t2 on t1.UserId = t2.UserId
try
SELECT UserId, COUNT(distinct Dept) Total
FROM MyTable
GROUP BY UserID
HAVING COUNT(distinct Dept) = 1
You can try something like this
select UserId, Dept
FROM Mytable where UserId in
(
SELECT UserId, COUNT(*) Total
FROM MyTable
GROUP BY UserID
HAVING COUNT(*) = 1
)
If you add the Dept column in your Group by you will always retrieve all the combinations.
So you have to select all users with only one Dept and then retrieve the additional informations
There is maybe syntax errors because I am usually working with oracle but I think the concept is correct
This will select users in 'hr' that do not have id's in 'customer' and then users in 'customer' that do not have ids in 'hr'.
I didn't include count on purpose as it can always only be one.
SELECT * FROM [MyTable] T WHERE Department = 'hr' AND NOT EXISTS (SELECT 1 FROM [MyTable] WHERE [MyTable].UserID =T.UserID AND Department = 'customer') UNION
SELECT * FROM [MyTable] T WHERE Department = 'customer' AND NOT EXISTS (SELECT 1 FROM [MyTable] WHERE [MyTable].UserID =T.UserID AND Department = 'hr')
I do not think the above query will run as Dept is not in group by clause and also count comparsion cannot be in that way.
Coming to your issue:
Select userid, Dept
from #temp
where userid in (Select userid from (Select userid,count(*) 'C'
from #temp group by userid ) u where u.c=1)
I do not think you require count as it is always 1
It's a fake question because you can't use Dept in this query.
I'm don't understand why author doesn't explain us about any compiler warnings and tells us some results of this query.
but you can yse this way if you really want to get some result:
SELECT UserId, min(Dept) as Dept
FROM MyTable
GROUP BY UserID
HAVING COUNT(*) = 1
The problem is the COUNT (*) at the end.
Try this:
SELECT UserId, Dept, COUNT(*) Total
FROM MyTable
GROUP BY UserID
HAVING COUNT(UserId) = 1
I'm looking for a way to handle the following scenario. I have a database table that I need to return only one record for each "group id" that is contained within the table, furthermore the record that is selected within each group should be the oldest person in the household.
ID Group ID Name Age
1 134 John Bowers 37
2 134 Kerri Bowers 33
3 135 John Bowers 44
4 135 Shannon Bowers 42
So in the sample data provided above I would need ID 1 and 3 returned, as they are the oldest people within each group id.
This is being queried against a SQL Server 2005 database.
SELECT t.*
FROM (
SELECT DISTINCT groupid
FROM mytable
) mo
CROSS APPLY
(
SELECT TOP 1 *
FROM mytable mi
WHERE mi.groupid = mo.groupid
ORDER BY
age DESC
) t
or this:
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY groupid ORDER BY age DESC) rn
FROM mytable
) x
WHERE x.rn = 1
This will return at most one record per group even in case of ties.
See this article in my blog for performance comparisons of both methods:
SQL Server: Selecting records holding group-wise maximum
Use:
SELECT DISTINCT
t.groupid,
t.name
FROM TABLE t
JOIN (SELECT t.groupid,
MAX(t.age) 'max_age'
FROM TABLE t
GROUP BY t.groupid) x ON x.groupid = t.groupid
AND x.max_age = t.age
So what if there's 2+ people with the same age for a group? It'd be better to store the birthdate rather than age - you can always calculate the age for presentation.
Try this (assuming Group is synonym for Household)
Select * From Table t
Where Age = (Select Max(Age)
From Table
Where GroupId = t.GroupId)
If there are two or more "oldest" people in some household (They all are the same age and there is noone else older), then this will return all of them, not just one at random.
If this is an issue, then you need to add another subquery to return an arbitrary key value for one person in that set.
Select * From Table t
Where Id =
(Select Max(Id) Fom Table
Where GroupId = t.GroupId
And Age =
(Select(Max(Age) From Table
Where GroupId = t.GroupId))
SELECT GroupID, Name, Age
FROM table
INNER JOIN
(
SELECT GroupID, MAX(Age) AS OLDEST
FROM table
) AS OLDESTPEOPLE
ON
table.GroupID = OLDESTPEOPLE.GroupID
AND
table.Age = OLDESTPEOPLE.OLDEST
SELECT GroupID, Name, Age
FROM table
INNER JOIN
(
SELECT GroupID, MAX(Age) AS OLDEST
FROM table
**GROUP BY GroupID**
) AS OLDESTPEOPLE
ON
table.GroupID = OLDESTPEOPLE.GroupID
AND
table.Age = OLDESTPEOPLE.OLDEST