SQL Server query to count - sql

I have two tables Invitations and Users, both table contain some emails.
I want to count those emails which are present in the Invitation table but not present in the Users table
Invitation
InvitationID Email
-------------------------------------
1 test#test.com
2 someone#example.com
3 test12#test.com
Users
UserName IsActive
-------------------------------------
test#test.com InActive
sample12#sample.com Active
test12#test.com InActive
I tried it like this
SELECT COUNT(*) FROM Invitations, Users
where Invitations.Email <> Users.UserName
I want like this
Count=1

You're getting the wrong answer because you're counting the wrong thing.
Imagine two records, a and b in each table. a<>b and b<>a so you'll get 2, not the 0 you're expecting.
Try this instead
Select count(*)
from Invitations
left join Users
on Invitations.Email = Users.UserName
where Users.UserName is null

You can try this one:
SELECT COUNT(*)
FROM Invitation
WHERE Email not in (
SELECT u.username
FROM Users
)

select count(*)
from Invitation i
where not exists (select 1 from Users u where i.email = u.userName)
This is simplest way in my opinion, you can event read it: count all rows in Invitation table where not exists a row in table Users where userName is equal email.

Related

Get only users who do not have the id equal to a condition (SQL)

I have two tables, user:
id
full_name
1
Beatriz
2
Mauro
3
Jose
4
fran
approver :
id
subordinate_id
approver_id
1
1
2
2
3
4
I would like to bring up the names of people who are not registered in the subordinate_id column
I did the following query:
SELECT
U.full_name
FROM user AS U
INNER JOIN approver as A
ON U.id <> A.subordinate_id ;
enter image description here
and still users are coming in that are in the subordinate_id column of the approver table.
I would like to get the result only for user names that are not subordinate_id, can someone help with this?
I would like a result with only the users that are not subordinate_id
This is simple to accomplish an ansi-sql with a not exists semi join:
Select full_name
from user u
where not exists (
select * from approver a
where a.approver_id = u.id <-- or (subordinate_id, whichever it should be)
);

Joining on a table but only match if it has at least one row based on a condition

I'm trying to find all users who have at least 1 transaction that has the StoreLocationID=123.
The basic query to get the count of users is:
SELECT COUNT(*)
FROM Users u
The transaction table looks like:
Transactions
- ID
- UserID
- Amount
- Date
- StoreLocationID
How can I find ALL users who have at least 1 transaction where StoreLocationID=123.
I can join on the table, but I just need to know if there is at least 1 row with StoreLocationID=123.
You can use a correlated subquery with an exists condition:
select *
from users u
where exists (
select 1
from transactions t
where t.userID = u.userID
and t.StoreLocationID = 123
)
This will give you all users that have at least one transaction on in store 123.
If you just want to count of such users, then:
select count(*)
from users u
where exists (
select 1
from transactions t
where t.userID = u.userID
and t.StoreLocationID = 123
)
Or:
select count(distinct userID) from transactions where StoreLocationID = 123

SQL selecting multiple record by different variable

Ok, so I have a table Assignment:
[UserId]
[GroupId]
[UpdatedBy]
[UpdatedAt]
Also, I have a function for returning users from a specific group:
select UserId
from dbo.GetGroupUsers() ggu
where ggu.GroupId = ?
In Assignment, I want to check all groups that our user is listed and then I want to select ALL users from these groups, without duplicate.
How can I achieve this?
Edit:
Sample output form selecting groupid = 4
for example user "test1" belong to other group where id=2 at the same time and i want selected all users from for example group 2 and 4 (cause in this example test1 said so) without records duplicate
All groups from one UserId (say UserId 10):
select GroupId from Assignment where UserId = 10
Select all users from those groups (without duplicate):
select distinct UserId
from dbo.GetGroupUsers() ggu
where ggu.GroupId in (select GroupId from Assignment where UserId = 10)
I hope this is what you wanted.
An inner self join should get you the IDs of the users you're looking for. Join the result with your user table (which you didn't post) to possibly get other information about these users.
SELECT DISTINCT
a2.userid
FROM assignment a1
INNER JOIN assignment a2
ON a2.groupid = a1.groupid
WHERE a1.userid = ?;
(Replace the ? with the ID of the user, you want to start with.)
Assuming your input is a user id:test1 and assuming that you are just looking at one table (Assignment)
DECLARE #UserId INT = 2
;WITH GROUPS AS
(
SELECT DISTINCT GroupId FROM Assignment WHERE UserId = #UserId
)
SELECT distinct assgn.UserName, gps.GroupId FROM Assignment assgn
INNER JOIN
GROUPS gps ON
assgn.GroupId = gps.GroupId
Please let me know if this helps

SQL query (Join without duplicates)

I have tables users and topics. Every user can have from 0 to several topics (one-to-many relationship).
How I can get only those users which have at least one topic?
I need all columns from users (without columns from topics) and without duplicates in table users. In last column I need number of topics.
UPDATED:
Should be like this:
SELECT user.*, count(topic.id)
FROM ad
LEFT JOIN topic ON user.id = topic.ad
GROUP BY user.id
HAVING count(topic.id) > 0;
but it takes 0 result. But it should not be 0.
Firstly you need to have your two tables, because you have left limited information about your table structure I will use an example to explain how this works, you should then be able to easily apply this to your own tables.
Firstly you need to have two tables (which you do)
Table "user"
id | name
1 | Joe Bloggs
2 | Eddy Ready
Table "topic"
topicid | userid | topic
1 | 1 | Breakfast
2 | 1 | Lunch
3 | 1 | Dinner
Now asking for a count against each user is done using the follwing;
SELECT user.name, count(topic.topicid)
FROM user
INNER JOIN topic ON user.id = topic.userid
GROUP BY user.name
If you use a left join, this will include records from the "user" table which does not have any rows in the "topic" table, however if you use an INNER JOIN this will ONLY include users who have a matching value in both tables.
I.e. because the user id "2" (which we use to join) is not listed in the topic table you will not get any results for this user.
Hope that helps!
use inner join and distinct
select distinct user_table.id
from user_table
inner join topics_table on topic_table.user_id = user_table.id
select u.id
, u.name
, count(b.topicName)
from user u
left join topic t on t.userid = u.id
group by u.id, u.name
You can select topic number per user and then join it with user data. Something like this:
with t as
(
select userid, count(*) as n
from topic
group by userid
)
SELECT user.*, t.n
FROM user
JOIN t ON user.id = t.userid

Deleting Records Based on Criteria

I have a list of users (Field = UserName) that I got from a table (Users). Some are duplicates.
Where there is a duplicate record, I need to delete the most current record (CreatedOn) created.
Also, if it trips up on the ability to delete because there are 'relationships established to this user ID' in the database, I need it to skip to the next record and continue deleting.
How do I accomplish this??
Adding on from Diego's answer with a check that the UserName is not the oldest instance in the table.
DELETE FROM
Users
WHERE
UserName IN
(SELECT UserName FROM Users GROUP BY UserName HAVING COUNT(UserName) > 1)
AND
CreatedOn !=
(SELECT MIN(CreatedOn) FROM Users T1 WHERE UserName = T1.UserName);
You can try something like this:
Delete from Users
where nameuser in
(select nameuser from Users
Group by nameuser
Having count(nameuser) > 1)
Use EXISTS to remove a row if same UserName also has an older CreatedOn:
delete from users u1
where exists (select 1 from users u2
where u2.UserName = u1.UserName
and u2.CreatedOn < u1.CreatedOn)
Or, another approach:
delete from users
where (UserName, CreatedOn) not in (select UserName, MIN(CreatedOn)
from users
group by UserName)
DELETE from user u
WHERE u.UserId in ( SELECT Distinct userid from User u join User u2 where u.UserName = u2.UserName
and u.CreatedOn > u2.CreatedOn)
You can't skip on error in one sql, but you could exclude userid that exists in related tables.