How to show all users name in SQL - sql

How to show all user name even count is zero.
$users = DB::select('select count(c.status) as countEvent, sum(c.point) as totalPoint,u.name from users u left join campaign_users c on u.id=c.user_id where u.deleted_at IS NULL group by u.name order by countEvent desc');
I want to count every user attend how many events but some of them not attend at all which is zero. I want to display all but the result only displayed users who attend at least one.
users - id, name
campaign_users - status (1 for pending, 2 for attend, 3 for absent), point

Assuming you are interested in countEvent and totalPoint values only for status = 2 (i.e. Attend)
SELECT u.name
,SUM(CASE WHEN c.status = 2 THEN 1 ELSE 0 END) AS countEvent
,SUM(CASE WHEN c.status = 2 THEN c.point ELSE 0 END ) AS totalPoint
FROM users u
LEFT JOIN campaign_users c
ON u.id=c.user_id
WHERE u.deleted_at IS NULL
GROUP BY u.name
It will be great if you can provide the sample data and intended output to understand your requirement clearly.

I guess one of the right way to do it is to query first the names and then count the results of the query .

Related

How to sum up max values from another table with some filtering

I have 3 tables
User Table
id
Name
1
Mike
2
Sam
Score Table
id
UserId
CourseId
Score
1
1
1
5
2
1
1
10
3
1
2
5
Course Table
id
Name
1
Course 1
2
Course 2
What I'm trying to return is rows for each user to display user id and user name along with the sum of the maximum score per course for that user
In the example tables the output I'd like to see is
Result
User_Id
User_Name
Total_Score
1
Mike
15
2
Sam
0
The SQL I've tried so far is:
select TOP(3) u.Id as User_Id, u.UserName as User_Name, SUM(maxScores) as Total_Score
from Users as u,
(select MAX(s.Score) as maxScores
from Scores as s
inner join Courses as c
on s.CourseId = c.Id
group by s.UserId, c.Id
) x
group by u.Id, u.UserName
I want to use a having clause to link the Users to Scores after the group by in the sub query but I get a exception saying:
The multi-part identifier "u.Id" could not be bound
It works if I hard code a user id in the having clause I want to add but it needs to be dynamic and I'm stuck on how to do this
What would be the correct way to structure the query?
You were close, you just needed to return s.UserId from the sub-query and correctly join the sub-query to your Users table (I've joined in reverse order to you because to me its more logical to start with the base data and then join on more details as required). Taking note of the scope of aliases i.e. aliases inside your sub-query are not available in your outer query.
select u.Id as [User_Id], u.UserName as [User_Name]
, sum(maxScore) as Total_Score
from (
select s.UserId, max(s.Score) as maxScore
from Scores as s
inner join Courses as c on s.CourseId = c.Id
group by s.UserId, c.Id
) as x
inner join Users as u on u.Id = x.UserId
group by u.Id, u.UserName;

SQL : one to many query on the many data

I'm having a really hard time figuring this out, hopefully someone can shed some light
Consider the following data
Users:
id username password
--------------------------
1 Bob 123
2 Alice abc
...
Services:
id user_id name status
-----------------------------
1 1 product1 canceled
2 1 product2 canceled
3 1 product3 live
4 2 product1 canceled
I need to do a query and find all users who only have canceled services. So the response should be "alice" only as bob has at least 1 live service.
If I try filter where status!='live' then (obviously) I still get Bob & Alice, how can I do a query where all the status is canceled is this possible?
Using exists logic we can try:
SELECT u.username
FROM Users u
WHERE NOT EXISTS (SELECT 1 FROM Services s
WHERE s.user_id = u.id AND s.status <> 'canceled');
This query says, in plain English, to find any users for which we cannot find in the Services table a record for that user whose status is not cancelled.
select distinct u.username from(
select * from service where status = 'canceled') canceled
inner join users u on u.id = canceled.user_id
where canceled.user_id not in(select user_id from service where status = 'live')
It selects all users which is not in the subset with the live status
Here is another way of approaching the problem
select distinct u.user_name from (
select user_id, sum(case when status = 'live' then 1 else 0 end) as live_cnt from services
group by user_id
having live_cnt = 0) s join users u on s.user_id =u.id
;

SQL query for checking if the result set is only from a given set of values

is there a good way to check for multiple combinations of conditions together? for example, if I have a COUNTRY table with id column in it and a VISITED table with country_id column in it. How can I check if every ID in VISITED table is either for 'Germany' or 'Nepal' or 'Brazil' but not from any fourth country. The VISITED IDs must be from these countries then YES otherwise NO.
COUNTRY
id, name
1, Germany
2, Nepal
VISITED
2
1
67
Result
NO
If VISITED table is like
VISITED
2
1
Result
YES
If VISITED table is like
VISITED
2
Result
YES
I am using SQL Server.
If I understand correctly then you want to define some arbitrary set of countries to check against. This set can be a subset of the country list. If all the VISITED IDs are from this set of countries then the result should be YES otherwise the result should be NO. Or the other way around, if VISITED contains any ID that is not in this set then the result should be NO and YES otherwise. Here the set is defined in the query as GermanyId, NepalId, BrazilId:
select case when exists
(select id from VISITED where id not in (GermanyId, NepalId, BrazilId))
then 'NO' else 'YES' end
Is that what you are after?
You can try to use JOIN then subquery in CASE WHEN
SELECT CASE WHEN (SELECT COUNT(ID) FROM VISITED) > COUNT(*) THEN 'NO' ELSE 'Yes' END
FROM COUNTRY c
JOIN VISITED v on c.id = v.id
sqlfiddle
One variant is to use LEFT JOIN and check if there are non-matching rows in Visited.
SELECT
CASE WHEN EXISTS
(
SELECT 1
FROM
Visited
LEFT JOIN Country ON Country.ID = Visited.CountryID
WHERE
Country.ID IS NULL
)
THEN 'NO'
ELSE 'YES'
END AS Result
;

Display record of 1 column comparing results of 2 column

I have provided with the table details and what is my expected output:
User (Id, PersonId, IsBlocked, BlockedReason)
Person (Id, FirstName, LastName)
Resume (Id, PersonId, IsActive)
Actual value would be
IsBlocked (Yes - 1 or No - 0 )
IsActive (Yes - 1 or No - 0)
I need to know whether the user is Blocked, Active, Inactive. User can be in only 1 among all these 3 status.
For example, if user is blocked, he will not be active - So overall I need only 1 status. How can I write a SQL query for this case?
In your case Person is the master table which contains all the people so you should left join the user and resume tables to that and use a case statement to get the status,
SELECT P.ID,P.FirstName,p.LastName,case when T.IsBlocked=1 then 'Blocked'
when R.IsActive =1 then 'Active'
else 'Inactive' end as user_status
FROM Person P
LEFT JOIN User U on P.ID=U.PersonId
LEFT JOIN Resume R on P.Id=R.PersonId
Use CASE statement
SELECT p.FirstName,p.LastName,
CASE WHEN t.IsBlocked=1 THEN 'Blocked'
WHEN r.IsActive =1 THEN 'Active'
ELSE 'Inactive' END as user_status
FROM User t JOIN Person p ON t.PersonId=p.Id
JOIN Resume r ON t.PersonId=r.PersonId

To display only the active status for one specific id and for same id all status should be disabled

I want to display person list who are Active for only one application starting 'a' and all other application should be 'DISABLED'.
Person id is in one table and application details will be in another table.
Have to select the Person id who is satisfies the following condition. I have attached the model result in which I have joined the three table . I need to select user as below(Highlighted),
person_id is a primary key.
The query used as follows:
SELECT * FROM (select p.person_id from ur_username u join ur_username_person up on u.username_id=up.username_id
join ur_person p on up.person_id=p.person_id
WHERE ( U.USERNAME LIKE 'A-%' OR U.USERNAME LIKE 'a-%')
AND u.status='ACTIVE' AND U.ROLE_ID =123 ) E
WHERE p.person_id IN ( select p.person_id from ur_username u join ur_username_person up on u.username_id=up.username_id
join ur_person p on up.person_id=p.person_id
WHERE ( U.USERNAME NOT LIKE 'A-%' OR U.USERNAME NOT LIKE 'a-%')
AND u.status='DISABLED' AND U.ROLE_ID =123 )
I am getting the person who is active in any other application also.
In that above table i want the username a-pri (starts with a-) also with status 'ACTIVE' all the other status for application id 123 is disabled . no other username is active for that 123 id.
We can try aggregating on the Application_id and then checking two things. First, we can check that a username a-pri who is active appears once, and only once. Second, we can assert that only one record appears as active. These two conditions would seem to meet your requirements.
SELECT
Application_id
FROM yourTable
GROUP BY
Application_id
HAVING
SUM(CASE WHEN username='a-pri' AND status='ACTIVE' THEN 1 ELSE 0 END) = 1 AND
SUM(CASE WHEN status = 'ACTIVE' THEN 1 ELSE 0 END) = 1;
Follow the link below which uses a larger sample data set to cover more edge cases.
Demo
Probably I do not correctly understand your request, but here is my code:
Select username from your_rable where status = 'ACTIVE';
If this is not what you intend to receive, please provide more dataset, maybe for more Application_id and also the needed result.