Issue related to Counting Record on Group by clause - sql-server

I have one database table having StudentId(int),Subject(varchar(50)),Marks(int),IsPass(int),ExamDate(Datetime)
Table can have more than one record for same Subject for particular student for different Date.
I wrote following query :
select StudentId, Count(IsPass)
from ExamEntry
where IsPass =1 group by StudentId
but dont want Where condition in the Query:
it is Possible something like this :
Select StudentId, case when IsPass = 1 then count(IsPass) end
from ExamEntry
group by studentId
but it display more that one record for perticular studentId
How can i achieve my goal ?

The answer is so simple nobody saw it :-)
SELECT StudentId, SUM(IsPass)
FROM ExamEntry GROUP BY StudentId

SELECT StudentId,
COUNT(CASE WHEN IsPass = 1 THEN 'X' END) AS NumberOfPasses
FROM ExamEntry
GROUP BY StudentId
COUNT only counts NOT NULL values and CASE has an implicit ELSE NULL

Perhaps You need something like this?
SELECT StudentId, SUM(CASE WHEN IsPass = 1 THEN 1 ELSE 0 END) AS Number_Of_Passed_Exams
FROM ExamEntry
GROUP BY StudentId

If you don't want to use where clause for it than Having clause is its simplest alternate.
Try this out.
select StudentId, count(IsPass)AS PassedCount
from ExamEntry
group by StudentId,IsPass
having IsPass= 1

Related

SQL In Select Statement show values from the same table but different records

I have a "Students" table with two columns "UserID" and "Name".
Next I have a table named "TestResults" with three columns, UserID, TestID, and TestScore.
I would like to run a single query that shows for each User, on ONE row, their test scores, for tests that have the TestID equal to 1A or 2A.
What approach is the best, I'm wondering if Pivot is the best way or is there another that is more advisable. Thanks.
Guessing on your comment, you can use conditional aggregation with max and case to get the results on a single row:
select s.userid, s.name,
max(case when t.testid = '1a' then t.testscore end) as 1ascore,
max(case when t.testid = '2a' then t.testscore end) as 2ascore
from students s
join testresults t on s.userid = t.userid
group by s.userid, s.name
Try this -
SELECT
UserID,
TestScore
FROM
TestResults
WHERE
(TestID = 1A)
OR (TESTID = 2A)

SQL Server : Combining Query Results

I have a program that stores different types "Assets" for buildings which can be marked as being "Removed". I can create a query to count the number of assets by type and another to count the number of items identified as still present. But what I want to do is combine the two into 1 table.
Query 1
SELECT
theAssetOutletType, COUNT(id) AS TotalNoOfAssets
FROM
dbo.tblLEGAssets
WHERE
buildingID = 1
GROUP BY
theAssetOutletType
Query 2
SELECT
theAssetOutletType, COUNT(id) AS ItemsStillPresent
FROM
dbo.tblLEGAssets
WHERE
buildingID = 1 AND removed <> 0
GROUP BY
theAssetOutletType
Thank you in advance for any help
I would suggest conditional aggregation:
SELECT theAssetOutletType,
COUNT(*) as TotalNoOfAssets
SUM(CASE WHEN removed <> 0 THEN 1 ELSE 0 END) as ItemsStillPresent
FROM dbo.tblLEGAssets
WHERE buildingID = 1
GROUP BY theAssetOutletType;
This puts the values in separate columns on the same row -- which makes more sense to me than on separate rows.
Try Union:
SELECT theAssetOutletType, count(id) as TotalNoOfAssets FROM dbo.tblLEGAssets where buildingID=1 group by theAssetOutletType
UNION
SELECT theAssetOutletType, count(id) as ItemsStillPresent FROM dbo.tblLEGAssets where buildingID=1 and removed<> 0 group by theAssetOutletType
I've found a work around, by using a nested select - that I can use, but if it is still possible I'd love to know the answer:
SELECT theassetoutlettype,
noofitems,
noremoved,
noofitems - noremoved AS noLeft
FROM (SELECT theassetoutlettype,
Count(id) AS NoOfItems,
Sum(removed) AS noRemoved
FROM dbo.tbllegassets
WHERE buildingid = 1
GROUP BY theassetoutlettype) nested
I finally found a solution... took a lot of trial and error but it now works. Here is my Stored Procedure Solution, with the additional table "tblLEGAssetOutletTypes" which contains a single fields with a list of the 6 asset types. The following code will always return 6 rows with the project type, the total number of assets, the number of assets removed and the total remaining. Hope someone else who needs a similar problem resolving an use the code:
SELECT tblLEGAssetOutletTypes.assetOutletType, nested.NoOfItems, nested.noRemoved, NoOfItems-noRemoved AS noLeft
FROM (SELECT theAssetOutletType, COUNT(id) AS NoOfItems, SUM(removed) AS noRemoved
FROM tblLEGAssets
where buildingID=#buildingID
GROUP BY theAssetOutletType) AS nested
RIGHT JOIN tblLEGAssetOutletTypes ON nested.theAssetOutletType = tblLEGAssetOutletTypes.assetOutletType;

Querying in SQL-

I have a table named "Results" like below:
I'd like to count personnel who have been completely scored. It means the ones who have no zero in score column. For example based on the uploaded picture just person with ID 1004 should be counted and the outcome should be one.
I used this code:
select Count(PrsID) from results
where Score <> 0
group by PrsID
But it wouldn't help me cause if a person has just one non-zero score, he will be counted!
Thanks in advance.
If I understand you correctly, I think this is what you want: SELECT COUNT(DISTINCT(PrsID)) FROM results WHERE PrsID NOT IN (SELECT DISTINCT PrsID FROM results WHERE score = 0)
If a person's min score is greater than zero, then they should be counted.
select count(1)
from (
select PrsID
from results
group by PrsID
having min(Score) > 0) as results
You can use conditional aggregation as below:
Select PrsId from results
group by PrsId
having sum(case when score = 0 then 1 else 0 end) > 1
I think you want something like:
select PrsID, Count(1) from results
where Score = 0
group by PrsID
This one returns count of person who has non zero score
SELECT
t1.PrsID,
Count(t1.PrsID)
FROM
( SELECT
*
FROM results
GROUP BY results.PrsID
ORDER BY results.Score ASC
) AS t1
WHERE t1.Score <> 0;

SQL Server - Nested Aggregation Functions

I want to do a nested aggregation, is this possible? SQL Server 2012 is returning an error when I try to do the following:
SELECT SUM(COUNT(memberID)) FROM table
The situation I have is the following:
I have members who have the same member ids as their dependents in the same table. I want to get the count of the the members and their dependents based on the memberID, however, I want the count in a column next to the main enrollee which is identified by another column as an e.
SELECT memberID, memberName, COUNT(memberID)
FROM table
WHERE memberRole = 'e'
The above would return 1 for all results, so I was thinking if I count the memberIds, then sum them would work but that returned an error, Am I doing something wrong? What is the best way to reach this porblem
Your original query was correct, with a slight change:
SELECT MemberID, MemberName, (SELECT COUNT(MemberID) FROM table WHERE MemberID = M.MemberID GROUP BY MemberID) AS MemberCount
FROM table M
WHERE M.MemberRole = 'E'
try this:
SELECT memberID, memberName, Sum(CNT) From
(
SELECT memberID, memberName, COUNT(memberID) CNt
FROM table
WHERE memberRole = 'e'
) t
group by memberID, memberName

SQL Server reference fields in derived table with unions

I'm having a bit of an issue with some derived tables that I hope someone will be able to help with. What I've got is 2 derived tables inside a select statement that then uses a pivot to display the results horizontally rather than vertically.
What I've got so far is:
SELECT * FROM(
SELECT SUM(Value) AS TotDays, ClassId FROM MainTable GROUP BY ClassId)
Union All
SELECT SUM(NumDays) As TotDays, ClassId FROM (
SELECT CASE WHEN COUNT(SiteId) > 0 THEN 1 ELSE 0 END AS NumDays
FROM Table2 GROUP BY ClassId ) as SUB
) AS a
PIVOT (SUM(TotDays) FROM ClassId
IN ([12],[13],[14],[15]
What I'm trying to do is reference the individual columns rather than using SELECT *, but I don't know how to do it. I can make it work without if I drop everything from the union onwards, but when I put the union in it doesn't work and I have to use SELECT *.
Anyone got any ideas on what's going wrong?
Thanks
Alex
You have a couple of errors on your query. For example, your UNION ALL has sets with a different number of columns, and you have other syntax errors. Try this way:
SELECT [12],[13],[14],[15]
FROM ( SELECT SUM(Value) AS TotDays, ClassId
FROM MainTable
GROUP BY ClassId
UNION ALL
SELECT SUM(NumDays) As TotDays, ClassId
FROM ( SELECT CASE WHEN COUNT(SiteId) > 0 THEN 1 ELSE 0 END NumDays,
ClassId
FROM Table2
GROUP BY ClassId) as SUB
) AS a
PIVOT (SUM(TotDays) FROM ClassId IN ([12],[13],[14],[15])) AS PT

Resources