Checking for value in list of rows per user - sql

I'm currently working with a list of survey data:
UserID
User Name
SurveyID
QuestionID
ResponseID
isSkipped
1
Test1
100
10
1
0
1
Test1
100
20
2
0
2
Test2
101
10
3
0
2
Test2
101
20
4
1
3
Test3
102
10
5
1
3
Test3
102
20
6
1
I'm looking for a query to give me the user, the SurveyID, and a flag (0 = Complete/1 = Not Complete) telling me if they completed all the questions (all the isSkipped values are 0)... so the end should be....
UserID
User Name
SurveyID
Complete
1
Test1
100
0
2
Test2
101
1
3
Test3
102
1
Can anyone help me out? I've tried using GROUP BY and SUM/COUNT and such, but I'm always getting more than one row per user. I'm sure it's something simple I'm missing.

Presumably, for your required result, you require:
select UserId, User_Name, SurveyId,
case when sum(isSkipped) > 0 then 1 else 0 end as Complete
from t
group by UserId, User_Name, SurveyId;

Since it's enough they completed one question to be considered complete then you can just choose max(isSkipped) for your complete status.
select UserID
,[User Name]
,SurveyID
,max(isSkipped) as Complete
from t
group by UserID, [User Name], SurveyID
UserID
User Name
SurveyID
Complete
1
Test1
100
0
2
Test2
101
1
3
Test3
102
1
Fiddle

Related

SQL Query to get multiple resultant on single column

I have a table that looks something like this:
id name status
2 a 1
2 a 2
2 a 3
2 a 2
2 a 1
3 b 2
3 b 1
3 b 2
3 b 1
and the resultant i want is:
id name total count count(status3) count(status2) count(status1)
2 a 5 1 2 2
3 b 4 0 2 2
please help me get this result somehow, i can just get id, name or one of them at a time, don't know how to put a clause to get this table at once.
Here's a simple solution using group by and case when.
select id
,count(*) as 'total count'
,count(case status when 3 then 1 end) as 'count(status1)'
,count(case status when 2 then 1 end) as 'count(status3)'
,count(case status when 1 then 1 end) as 'count(status2)'
from t
group by id
id
total count
count(status3)
count(status2)
count(status1)
2
5
1
2
2
3
4
0
2
2
Fiddle
Here's a way to solve it using pivot.
select *
from (select status,id, count(*) over (partition by id) as "total count" from t) tmp
pivot (count(status) for status in ([1],[2],[3])) pvt
d
total count
1
2
3
3
4
2
2
0
2
5
2
2
1
Fiddle

Select from same column but multiples values and number of records with one specific value

ID Customer Status
1 ABC 1
2 ABC 2
3 ABC 3
4 ABC 1
5 PQR 1
6 PQR 2
7 PQR 3
8 XYZ 1
9 XYZ 3
I want to select customer who has both values "status=1" and "Status=2' and also total number of entry of same customer with Status=1.
So the result will be,
Customer totalEntryStatus1
ABC 2
PQR 1
How can I do this.
Thankyou !
select Customer, count(case when status = 1 then 1 end) totalEntryStatus1
from table
where Status in (1,2)
group by Customer
having count(distinct Status) = 2

How to get all columns when you do group by for multiple columns?

Here is my table
UserDetail
Id UserId CourseId SubjectId TeacherCode RDate status
1 1 1 1 1 08/02/2016 Waiting
2 1 1 1 2 08/01/2016 Recceived
3 1 1 1 3 08/02/2016 Processed
4 1 1 2 1 08/03/2016 Recceived
5 1 1 2 2 08/04/2016 Processed
6 1 2 1 3 08/05/2016 Processed
7 1 2 2 1 08/06/2016 Processed
User can have multiple courses,multiple subjects.One teacher can teach multiple subject.I want to fetch all column from table, base on distinct userid,courseid and subjectid.Out of 7 row,want to show only 4 rows.
Any one record from below
Id UserId CourseId SubjectId TeacherCode RDate status
1 1 1 1 1 08/02/2016 Waiting
2 1 1 1 2 08/01/2016 Recceived
3 1 1 1 3 08/02/2016 Processed
If we pick teachercode 1,then rdate to be 08/02/2016 and status to be Waiting
neither Recceived nor Processed.
Any one from below
Id UserId CourseId SubjectId TeacherCode RDate status
4 1 1 2 1 08/03/2016 Recceived
5 1 1 2 2 08/04/2016 Processed
How to do that?
You gotta know which rows of that distincted datas you want to choose. First rows ? Last rows ?
Since for every group of distincted data would be multiple rows so you mist choose which row you want.
I assume you want the first row from every distincted group. You can do it like below:
Select first(Id) AS Id, first(UserId) AS UserId, first(CrouseId) AS CourseId, first(SubjectId) AS SubjectId, first(TeacherId) AS TescherId,first(RDate) AS RDate, first(status) as status
FROM UserDetail
Group By UserId, CourseId, SubjectId
In sql2005+, do it like below:
WITH temp AS (
SELECT *,
ROW_NUMBER() OVER(PARTITION BY UserId,CourseId,SubjectId ORDER BY Id) AS rn FROM UserDetail)
SELECT t.*
FROM temp t
WHERE t.rn = 1
Or you can do it using inner select instead of WITH:
SELECT *
FROM (SELECT *,
ROW_NUMBER() OVER(PARTITION BY UserId,CourseId,SubjectId ORDER BY Id) AS rn FROM UserDetail)
WHERE rn = 1

An update with multiple conditions. SQL 2008

I have a table...
ProjectID UserID RoleID
101 1 10
101 2 10
102 2 10
102 3 10
103 1 10
Currently there is only one type of Role, role '10', but I'm wanting to add a new role, role '11', which will act as a lead. So any project that has a user with the role of '10', should have a lead. The user chosen to be lead will be based on a priorty list, in this example we'll say the order is 1, 2, 3.
Expected result...
ProjectID UserID RoleID
101 1 11
101 2 10
102 2 11
102 3 10
103 1 11
You can figure out which user has the highest priority by using row_number(). SQL Server let's you do this in an updatable CTE, so the query looks like this:
with toupdate as (
select t.*,
row_number() over (partition by projectid
order by (case when userid = 1 then 1
when userid = 2 then 2
when userid = 3 then 3
else 4
end
)
) as PriorityForLead
from table t
)
update toupdate
set RoleId = 11
where PriorityForLead = 1;

Matching two variables to create a new ID

I'm trying to create an SQL statement to match either an id number or a postcode and then assign a new id number
What I want to end up with is ‘newid’ that correctly recognizes that the first four records are the same person (even though the postcode for record 2 is different).
record id postcode newid
--------------------------
1 1 1 1
2 1 2 1
3 1 1 1
4 2 1 1
5 3 3 2
Any suggestions would be appreciated greatly.
Going based on your example:
SELECT RECORD,
(SELECT MIN (ID)
FROM users u2
WHERE users.id IN (u2.id, u2.postcode)
OR users.postcode in (u2.id, u2.postcode)
) AS newid
FROM users
This results with the following data:
RECORD NEWID
------------------
1 1
2 1
3 1
4 1
5 3
Here is the SQLFiddle