Replace select into table by sub query - sql-server

I have the following code I need to write subquery to return the same result.
SELECT Users.UserID,
Users.FirstName,
courses.CourseID,
Count(Exams.examID)NumExams into CurrentExams
FROM ClassCourses
INNER JOIN courses ON ClassCourses.CourseID = courses.CourseID
INNER JOIN Exams ON ClassCourses.ClassID = Exams.ClassID
AND ClassCourses.CourseID = Exams.CourseID
INNER JOIN UserExams ON Exams.ExamID = UserExams.ExamID
INNER JOIN Users ON UserExams.UserID = Users.UserID
group by Users.UserID, courses.CourseID, Users.FirstName
IF EXISTS (SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'AllExams')
drop table AllExams
SELECT courses.CourseID, count(ExamID) TotalExams into AllExams
FROM Exams
INNER JOIN courses ON Exams.CourseID = courses.CourseID
group by Courses.CourseID
SELECT CurrentExams.FirstName,
CurrentExams.CourseID,
AllExams.TotalExams,
AllExams.TotalExams-CurrentExams.NumExams AS Unlisted
FROM AllExams
inner JOIN CurrentExams on CurrentExams.CourseID=AllExams.CourseID

Here is a simple version of one query for what you need. Assuming you have sql server 2005 or later versions.
;with CurrentExams as
(
SELECT Users.UserID, Users.FirstName,courses.CourseID,Count(Exams.examID)NumExams
FROM
ClassCourses
INNER JOIN
courses ON ClassCourses.CourseID = courses.CourseID INNER JOIN
Exams ON ClassCourses.ClassID = Exams.ClassID AND ClassCourses.CourseID = Exams.CourseID INNER JOIN
UserExams ON Exams.ExamID = UserExams.ExamID INNER JOIN
Users ON UserExams.UserID = Users.UserID
group by Users.UserID,courses.CourseID, Users.FirstName
),
AllExams as
(
SELECT courses.CourseID,count(ExamID) TotalExams
FROM
Exams
INNER JOIN
courses ON Exams.CourseID = courses.CourseID
group by Courses.CourseID
)
SELECT CurrentExams.FirstName, CurrentExams.CourseID, AllExams.TotalExams,AllExams.TotalExams-CurrentExams.NumExams AS Unlisted
FROM
AllExams
inner JOIN CurrentExams on CurrentExams.CourseID=AllExams.CourseID

Related

T-SQL query not grouping results in output

I have the follwoing query embedded in a stored procedure
select u.UserName, s.Name, count(i.id) as NumberAccounts, sum(i.total) as CCTotal
from invoice i
inner join visit v on v.id = i.id
inner join branch b on b.id = v.branchid
inner join practice p on p.id = b.practiceid
inner join visitscheme vs on vs.id = v.id
inner join [plan] pl on pl.id = vs.planid
inner join scheme s on s.id = pl.schemeid
inner join creditcontrol cc on cc.SchemeId = s.id
inner join [user] u on u.id = cc.userid
where p.APIKey = #pracId
and (u.id = #CCid OR #CCId = '999999')
and (s.id = #SchemeId or #SchemeId = 999999)
group by u.UserName, s.Name
order by u.username
When I run it instead of result being grouped by username and scheme I get the following
UserName Name NumberAccounts CCTotal
chanel BANKMED 9954 11882514.19
ciske BANKMED 9954 11882514.19
Estee BANKMED 9954 11882514.19
Feroza BANKMED 9954 11882514.19
No grouping applied, the same values in each. Anyone know where I am going wrong?
Thanks
just write like this....
select u.UserName, s.Name, count(i.id) as NumberAccounts, sum(i.total) as CCTotal
from invoice i
inner join visit v on v.id = i.id
inner join branch b on b.id = v.branchid
inner join practice p on p.id = b.practiceid and p.APIKey = #pracId
inner join visitscheme vs on vs.id = v.id
inner join [plan] pl on pl.id = vs.planid
inner join scheme s on s.id = pl.schemeid and (s.id = #SchemeId or #SchemeId = 999999)
inner join creditcontrol cc on cc.SchemeId = s.id
inner join [user] u on u.id = cc.userid and (u.id = #CCid OR #CCId = '999999')
group by u.UserName, s.Name
order by u.username
assuming that your joins are correct

Get Max(id) from one to many table

I know this question was asked many times but I was tring and trying without success
I have one to many relationship between two tables and some more inner-joins to get more data.
Here is my query:
SELECT
ShopOffer.OfferID,
ShopOffer.OfferMessage,
Shop.ID,
Shop.Name,
Shop.Phone,
[User].Name,
[User].UserID,
ShopOfferStatus.Name AS StatusName,
BlockedShopInUser.IsBlocked
FROM
ShopOffer
INNER JOIN ShopOfferStatus ON ShopOffer.ShopOfferStatusID = ShopOfferStatus.ShopOfferStatusID
INNER JOIN Shop ON ShopOffer.ShopID = Shop.ShopID
INNER JOIN UserRequest ON ShopOffer.UserRequestID = UserRequest.UserRequestID
INNER JOIN [User] ON UserRequest.UserID = [User].UserID
INNER JOIN BlockedShopInUser ON Shop.ShopID = BlockedShopInUser.ShopID AND [User].UserID = BlockedShopInUser.UserID
Each shop can create many offers. In that query I would like to get only the last offer for each shop.
Thanks.
Here is a way:
;WITH LastShopOffer AS
(
SELECT *,
RN = ROW_NUMBER() OVER(PARTITION BY ShopID ORDER BY OfferID DESC)
FROM ShopOffer
)
SELECT
SO.OfferID,
SO.OfferMessage,
S.ID,
S.Name,
S.Phone,
U.Name,
U.UserID,
SOS.Name AS StatusName,
B.IsBlocked
FROM ( SELECT *
FROM LastShopOffer
WHERE RN = 1) SO
INNER JOIN ShopOfferStatus SOS
ON SO.ShopOfferStatusID = SOS.ShopOfferStatusID
INNER JOIN Shop S
ON SO.ShopID = S.ShopID
INNER JOIN UserRequest UR
ON SO.UserRequestID = UR.UserRequestID
INNER JOIN [User] U
ON UR.UserID = U.UserID
INNER JOIN BlockedShopInUser B
ON S.ShopID = B.ShopID
AND U.UserID = B.UserID;
I think you have to start with Shop and then perform a CROSS APPLY on the TOP 1 record from ShopOffer:
SELECT
ShopOffer.OfferID,
ShopOffer.OfferMessage,
Shop.ID,
Shop.Name,
Shop.Phone,
[User].Name,
[User].UserID,
ShopOfferStatus.Name AS StatusName,
BlockedShopInUser.IsBlocked
FROM Shop
CROSS APPLY (
SELECT TOP 1 OfferID, OfferMessage, ShopOfferStatusID, UserRequestID
FROM ShopOffer AS s
WHERE s.ShopID = Shop.ShopID
ORDER BY s.OfferID DESC
) ShopOffer
INNER JOIN ShopOfferStatus ON ShopOffer.ShopOfferStatusID = ShopOfferStatus.ShopOfferStatusID
INNER JOIN UserRequest ON ShopOffer.UserRequestID = UserRequest.UserRequestID
INNER JOIN [User] ON UserRequest.UserID = [User].UserID
INNER JOIN BlockedShopInUser ON Shop.ShopID = BlockedShopInUser.ShopID AND [User].UserID = BlockedShopInUser.UserID

How to use Having instead of where SQL SERVER

i'm writing query to find the number of student who got marks between 1-50 and 50-70 and 70-100
i tried to solve it but all i did is retrieve the student who got marks between 1-50 just
i need to retrieve the other values (between 50-70 and 70-100)
;with StudentMarks as
(
SELECT Users.UserID,classes.Name Class, courses.Name AS Course, Sum(UserExams.StudentMark) Tot
FROM ClassCourses INNER JOIN classes ON ClassCourses.ClassID = classes.ClassID
INNER JOIN courses ON ClassCourses.CourseID = courses.CourseID
INNER JOIN Exams ON ClassCourses.ClassID = Exams.ClassID AND ClassCourses.CourseID = Exams.CourseID
INNER JOIN SectionsClasses ON classes.ClassID = SectionsClasses.ClassID
INNER JOIN UserExams ON Exams.ExamID = UserExams.ExamID
INNER JOIN Users ON SectionsClasses.SectionID = Users.SectionID AND SectionsClasses.ClassID = Users.ClassID AND UserExams.UserID = Users.UserID
Group by Users.UserID, classes.Name ,courses.Name
)
SELECT Class,Course,
count(UserID)'1-50'
from StudentMarks
where tot between 1 and 50
Group by Class,Course
can anyone help please ?
You can use case
;with studentmarks as (....)
select
class,
course,
case when tot<=49 then '0-49'
when tot>=71 then '71+'
else '50-70' end as gp,
count(userid)
from studentmarks
group by
class,
course,
case when tot<50 then '0-49' when tot>70 then '71+' else '50-70' end
this work nice
select Class,Course,SUM(case when tot between 1 and 50 then 1 else 0 end )'1-50'
,SUM(case when tot between 50 and 70 then 1 else 0 end )'50-70'
,SUM(case when tot between 70 and 100 then 1 else 0 end )'70-100'
FROM
(
SELECT Users.UserID,classes.Name Class, courses.Name AS Course, Sum(UserExams.StudentMark) Tot
FROM ClassCourses INNER JOIN classes ON ClassCourses.ClassID = classes.ClassID
INNER JOIN courses ON ClassCourses.CourseID = courses.CourseID
INNER JOIN Exams ON ClassCourses.ClassID = Exams.ClassID AND ClassCourses.CourseID = Exams.CourseID
INNER JOIN SectionsClasses ON classes.ClassID = SectionsClasses.ClassID
INNER JOIN UserExams ON Exams.ExamID = UserExams.ExamID
INNER JOIN Users ON SectionsClasses.SectionID = Users.SectionID AND SectionsClasses.ClassID = Users.ClassID AND UserExams.UserID = Users.UserID
WHERE courses.CourseID =#pCourseID
Group by Users.UserID, classes.Name ,courses.Name
)AS SQ
GROUP BY Class,Course

Find Max value of sum Using SQL server

I have this query i need to alter it to find the max of Sum(StudentMark)
SELECT Users.UserID,
ClassCourses.CourseID,
sum(StudentMark)SumOFMarks
FROM Users
INNER JOIN UserExams
ON Users.UserID = UserExams.UserID
INNER JOIN Exams
ON UserExams.ExamID = Exams.ExamID
INNER JOIN ClassCourses
ON Exams.ClassID = ClassCourses.ClassID
AND Exams.CourseID = ClassCourses.CourseID
GROUP BY Users.UserID,
ClassCourses.CourseID
Wrap this in a CTE and query the CTE:
;WITH MyCTE AS
(
SELECT Users.UserID,
ClassCourses.CourseID,
sum(StudentMark)SumOFMarks
FROM Users
INNER JOIN UserExams
ON Users.UserID = UserExams.UserID
INNER JOIN Exams
ON UserExams.ExamID = Exams.ExamID
INNER JOIN ClassCourses
ON Exams.ClassID = ClassCourses.ClassID
AND Exams.CourseID = ClassCourses.CourseID
GROUP BY Users.UserID,
ClassCourses.CourseID
)
SELECT MAX(SumOFMarks)
FROM MyCTE
this works good
Create procedure [dbo].[MaxMinMarks]
(
#pClassID int
)
as
--check if the table exists then if true delete it because we'll create it every time the SP run
IF EXISTS (SELECT *
FROM INFORMATION_SCHEMA.TABLES
WHERE
TABLE_NAME = 'StudentMarks')
drop table StudentMarks
SELECT ClassCourses.ClassID,ClassCourses.CourseID,ClassCourses.MaxMark,sum(StudentMark)SumOFMarks
--store result into new table
into StudentMarks
FROM Users INNER JOIN
UserExams ON Users.UserID = UserExams.UserID INNER JOIN
Exams ON UserExams.ExamID = Exams.ExamID INNER JOIN
ClassCourses ON Exams.ClassID = ClassCourses.ClassID AND Exams.CourseID = ClassCourses.CourseID
where ClassCourses.ClassID=#pClassID
group by Users.UserID, ClassCourses.ClassID,ClassCourses.CourseID,ClassCourses.MaxMark
--useing the new table we can find max and min marks
select ClassID,CourseID,MaxMark,max(SumOFMarks) highestMark,min(SumOFMarks)LowestMark from StudentMarks
group by ClassID,CourseID,MaxMark

Aggregate Function alias from select used in where clause

Where is the error here:
SELECT Users.UserID,
ClassCourses.CourseID,
ClassCourses.MinMark,
sum(StudentMark) as SMark
FROM Users
INNER JOIN UserExams ON Users.UserID = UserExams.UserID
INNER JOIN Exams ON UserExams.ExamID = Exams.ExamID
INNER JOIN ClassCourses ON Exams.ClassID = ClassCourses.ClassID AND Exams.CourseID = ClassCourses.CourseID
where ClassCourses.MinMark> SMark
group by Users.UserID, ClassCourses.CourseID,ClassCourses.MinMark
I got an error:
Invalid column name 'SMark'.
You can not use column aliases in your WHERE clause. Also, when comparing results of aggregations, you must use the HAVING clause, after the GROUP BY is applied.
Do something like this:
SELECT Users.UserID,
ClassCourses.CourseID,
ClassCourses.MinMark,
sum(StudentMark) as SMark
FROM Users
INNER JOIN UserExams ON Users.UserID = UserExams.UserID
INNER JOIN Exams ON UserExams.ExamID = Exams.ExamID
INNER JOIN ClassCourses ON Exams.ClassID = ClassCourses.ClassID AND Exams.CourseID = ClassCourses.CourseID
GROUP BY Users.UserID, ClassCourses.CourseID,ClassCourses.MinMark
HAVING ClassCourses.MinMark > sum(StudentMark)
try this one:
select
*
from
(
SELECT Users.UserID,
ClassCourses.CourseID,
ClassCourses.MinMark,
sum(StudentMark) as SMark
FROM Users
INNER JOIN UserExams ON Users.UserID = UserExams.UserID
INNER JOIN Exams ON UserExams.ExamID = Exams.ExamID
INNER JOIN ClassCourses ON Exams.ClassID = ClassCourses.ClassID AND Exams.CourseID = ClassCourses.CourseID
group by Users.UserID, ClassCourses.CourseID,ClassCourses.MinMark
)a
where MinMark > SMark
You can't use the alias in the WHERE clause, because the WHERE statement is logically executed before the SELECT, so it doesn't see that name SMark.
You can put it in a subquery instead, and filter in the outer one like this:
SELECT *
FROM
(
SELECT
Users.UserID,
ClassCourses.CourseID,
ClassCourses.MinMark,
sum(StudentMark) as SMark
FROM Users
INNER JOIN UserExams ON Users.UserID = UserExams.UserID
INNER JOIN Exams ON UserExams.ExamID = Exams.ExamID
INNER JOIN ClassCourses ON Exams.ClassID = ClassCourses.ClassID
AND Exams.CourseID = ClassCourses.CourseID
group by Users.UserID,
ClassCourses.CourseID,
ClassCourses.MinMark
) AS t
where MinMark> SMark

Resources