SQL: To obtain single record for each CourseId - sql-server

I'm naive to SQL...pls help me with my below query:
I have a table named Course as shown below:
Key CourseName CourseId IsCurrentVersion
0 Course_1 A 0
1 Course_1 A 0
2 Course_1 A 1
3 Course_2 B 0
4 Course_2 B 0
5 Course_3 C 1
6 Course_4 D 0
7 Course_5 E 0
8 Course_5 E 0
9 Course_6 F 1
10 Course_6 F 1
11 Course_6 F 1
12 Course_7 G 1
13 Course_7 G 0
14 Course_7 G 0
I want the below result set:
CourseName CourseId IsCurrentVersion
Course_1 A 1
Course_2 B 0
Course_3 C 1
Course_4 D 0
Course_5 E 0
Course_6 F 1
Course_7 G 1
For records having same CourseId; IsCurrentVersion having 1 should be preferred to 0. Single records should also get displayed in output irrespective of their IsCurrentVersion values.
Database is SQL Server 2008.

Try this:
SELECT CourseName, CourseId, IsCurrentVersion
FROM Course AS A
WHERE IsCurrentVersion = (SELECT MAX(IsCurrentVersion)
FROM Course AS B
WHERE A.CourseId = B.CourseId)
GROUP BY CourseName, CourseID, IsCurrentVersion

This should get you what you are looking for, assuming the only values for IsCurrentVersion are 1 and 0.
SELECT CourseName, CourseId, MAX(IsCurrentVersion)
FROM Course
GROUP BY CourseName, CourseID
If the IsCurrentVersion column is a bit and not an integer, use this instead.
SELECT CourseName, CourseId, MAX(CASE WHEN IsCurrentVersion = 1 THEN 1 ELSE 0 END)
FROM Course
GROUP BY CourseName, CourseID

Related

Self Cross apply table data

I have a below table
ID Level StoreId
2678540 3 A
2678540 7 A
2678540 3 B
2678540 7 B
2678540 3 C
I need out put like Below
ID A B C D E
2678540 3 3 3 0 0
2678540 3 7 3 0 0
2678540 7 3 3 0 0
2678540 7 7 3 0 0
Please help me how to achieve this.
If StoreID 'A' always exists:
select tA.ID, tA.Level as A, tB.Level as B, tC.Level as C , 0 as D, 0 as E
from Table1 tA
cross apply (select Level from Table1 t2 where tA.Id=t2.Id and t2.StoreId = 'B') tB
cross apply (select Level from Table1 t2 where tA.Id=t2.Id and t2.StoreId = 'C') tC
where tA.StoreId = 'A'

Check if value exist for multiple records and get one record

I have two tables.Department as follows
ID DName
1 IT
2 HR
3 Admin
Employee as follows
id fname departmentid
1 Mary 2
2 Rahul 2
3 Amit 3
4 Vivek 1
5 Preetam 1
6 Mangesh 1
7 Mary 1
Observe that there are two records for Mary (id 1 and 7) in employee table. Now I want to get result with name of employee and whether it works in HR department or not. Expected output is as follows.
fname WorksInHR
Mary Y
Rahul Y
Amit N
Vivek N
Preetam N
Mangesh n
How can i achieve this in SQL2012?
Here is one way of doing this:
select e.fname,
(case when sum(case when d.dname = 'HR' then 1 else 0 end) > 0
then 'Y' else 'N'
end) as WorksInHR
from employee e join
department d
on e.departmentid = d.id
group by e.fname;

In SQL Server, Split bit column to 2 columns using PIVOT

I have a table as below
Name Grade SubjectAorB
Pooja B 1
Preeti C 0
Preeti C 1
Chintu A 1
Deepika B 0
Deepika B 1
Peter A 0
John A 0
Last column SubjectAorB has values as 0 and 1. 0 means Subject A and 1 means Subject B. A student can have either of the subject or both. I want output as below:
Name Grade Subject A Subject B
Pooja B 0 1
Preeti C 1 1
Chintu A 0 1
Deepika B 1 1
Peter A 1 0
John A 1 0
You can do this using conditional aggregation:
SELECT
Name,
Grade,
SubjectA = MAX(CASE WHEN SubjectAorB = 0 THEN 1 ELSE 0 END),
SubjectB = MAX(CASE WHEN SubjectAorB = 1 THEN 1 ELSE 0 END)
FROM #tbl
GROUP BY Name, Grade

A group by challenge

Let's say I have this table MyTbl
Record Id_try Id Type IsOk DateOk
1 1 MYDB00125 A 0 NULL
2 1 MYDB00125 B 1 2012-07-19 20:10:05.000
3 1 MYDB00125 A 0 2012-07-25 14:10:05.000
4 2 MYDB00125 A 0 2012-07-19 22:10:05.000
5 1 MYDB00254 B 0 2012-07-19 22:10:05.000
6 1 MYDB00254 A 0 NULL
7 3 MYDB00125 A 1 2012-07-19 22:15:05.000
8 3 MYDB00125 B 1 2012-07-19 22:42:53.000
9 1 MYDB00323 A 1 2012-07-22 00:15:05.00 0
10 1 MYDB00323 C 0 NULL
And I want a group by that brings me for each Id and Type my last "Id_Try Record".
SELECT Id, MAX(Id_Try), MyTbl.Type, IsOK, MAX(DateOk) from MyTbl
GROUP BY Id, MyTbl.Type, IsOK
Won't do, because It'll bring me the last Id_Try AND the last date (Date of record 3 in the example). And I don't care if its the last date or not, I need the date of the last Id_Try.
Is this only solved by a subselect? or a having clause could do?
This is the result expected:
Record Id_try Id Type IsOk DateOk
5 1 MYDB00254 B 0 2012-07-19 22:10:05.000
6 1 MYDB00254 A 0 NULL
7 3 MYDB00125 A 1 2012-07-19 22:15:05.000
8 3 MYDB00125 B 1 2012-07-19 22:42:53.000
9 1 MYDB00323 A 1 2012-07-22 00:15:05.00 0
10 1 MYDB00323 B 0 NULL
I think you will need to break this into two pieces:
with maxIDTry as
(
SELECT MAX(Id_try) as maxId, ID
FROM MyTable
GROUP BY ID
)
SELECT * FROM MyTable as mt
INNER JOIN maxIDTry as max
ON mt.id_try = max.maxId AND mt.id = max.id
I think you want this:
select * FROM
(
select *, row_number() over (partition by id,type order by Id_try desc) as position from mytbl
) foo
where position = 1
order by record
http://www.sqlfiddle.com/#!3/95742/5
Your sample result set lists
9 1 MYDB00323 A 1 2012-07-22 00:15:05.00 0
10 1 MYDB00323 A 0 NULL
But that doesn't make sense since you're saying the ID and the Id_try have the same value. I assume you meant for Id_try to be 2 maybe? Otherwise I think my results match up.
Hope this helps.
SELECT A.Record, A.Id_try, A.Id, A.Type, A.IsOk, A.DateOk
FROM MyTbl A INNER JOIN (
SELECT MAX(Id_Try) Id_Try, Id, B1.Type
from MyTbl B1
GROUP BY Id, B1.Type) AS B
ON A.Id_Try = B.Id_Try AND A.Id = B.Id AND A.Type = B.Type
ORDER BY A.RECORD

How to assign an alternating row number based on a table primary key?

I have a table with data named Product
ProductID ProductName
1 ABC
2 PQR
3 XYZ
4 HJK
5 LKJ
6 MNB
... ....
with many more product in it. What I want is result like this on Select query:
RowNo ProductID ProductName
1 1 ABC
1 2 PQR
2 3 XYZ
2 4 HJK
1 5 LKJ
1 6 MNB
2 7 klj
2 8 hjg
then 1,1, 2,2 1,1 for the number of records in the table. Is it possible, and if so how can I do that?
This works for your sample data which assumes ProductID is contiguous:
SELECT
CASE WHEN ProductID % 4 = 0 OR (ProductID+1) % 4 = 0 THEN 2 ELSE 1 END,
ProductID,
ProductName
FROM
Product
Now, guessing that you mean in resultset which may have gaps in ProductID
SELECT
CASE WHEN ContiguousProductID % 4 = 0 OR (ContiguousProductID+1) % 4 = 0 THEN 2 ELSE 1 END,
--ContiguousProductID,
--CASE WHEN ProductID % 4 = 0 OR (ProductID+1) % 4 = 0 THEN 2 ELSE 1 END,
ProductID,
ProductName
FROM
(
SELECT
ROW_NUMBER() OVER (ORDER BY ProductID) AS ContiguousProductID,
ProductName, ProductID
FROM
dbo.Product
) P2

Resources