a great select query including count - sql-server

I have around 20 tables including examination records of students. I tried to figure out my question
(Student ID = sID, i.e. Score 1 : s1) :
StudentsTables : (student reg.data)
sID name surname regDate photo ........
891 Mike Jackson 01.01.2013 82342984.png ....
TableA : (student scores)
sID exam s1 s2 s3 s4
891 6 0 0 0 20 > student 891 attended exam 6
891 10 30 80 100 75 > student 891 attended exam 10
(count = 2)
TableB : (student documents , i.e. : document 1 : d1)
sID d1 d2 d3 d4 d5 d6
891 true false true true true true
(count = 1)
TableC : (student messages)
mID from to subject message
1 10 891 any sub. any message... > student 891 received messages (look "to")
1 10 891 mes2 other message...
1 29 891 mes3 another message...
(count = 3)
TableD : (student payments)
sID pID amount date details
(no student record in this table, count = 0)
..... and similar tables like above.
I want a result like below :
sID name surname scoreCount docCount messageCount paymentCount .....
891 Mike Jackson 2 1 3 0 ...
892 Susan Button 0 3 10 0 ...
893 Ahmad Malisi 1 0 5 2 ...
894 any any 4 1 0 0 ...
...
..

Have you tried this
Select sid,name,surname,
(Select count(*) From student_scores Where Sid = S.Sid ) as scoreCount ,
(Select count(*) From student_documents Where Sid = S.Sid ) as docCount ,
(Select count(*) From student_messages Where to= S.Sid ) as messageCount ,
(Select count(*) From student_payments Where Sid = S.Sid ) as paymentCount ,
.
.
.
From StudentsTables S
Where Sid=891

Select sid,name,surname,
isnull(sscnt,0) ,isnull(sdcnt ,0) ,isnull(spcnt ,0) ,isnull(smcnt,0)
From StudentsTables S
join (Select Sid,count(Sid) sscnt From student_scores group by Sid) ss
on ss.sid=s.sid
join (Select Sid,count(Sid) sdcnt From student_documents group by Sid) sd
on sd.sid=s.sid
join (Select Sid,count(Sid) spcnt From student_payments group by Sid) sp
on sp.sid=s.sid
join (Select Sid,count(Sid) smcnt From student_messages group by Sid) sm
on sm.sid=s.sid
this will query for all SId (s)

Related

Convert rows to column headers with totals

I have the following query:
SELECT
g.Gender,
a.AgeGroup,
count(*) as Count
FROM
client c
INNER JOIN AgeGroup a
ON c.age BETWEEN a.StartRange AND a.EndRange
INNER JOIN Gender G on
C.GenderID = G.GenderID
group by
g.Gender,
a.AgeGroup
order by AgeGroup, Gender
which gives the following results:
Gender AgeGroup Count
Male <=25 4
Unknown <=25 2
Female >35 2223
Male >35 6997
Transgender >35 43
Unknown >35 2
Female 26-35 413
Male 26-35 590
Transgender 26-35 5
What I'm needing to try and do though is convert the Gender column to column headers and include totals.
AgeGroup Male Female Trans Unknown Total
<= 25: 4 0 0 2 6
26 - 35: 590 413 5 0 1008
> 35: 6997 2223 43 2 9265
Total: 7591 2636 48 4 10279
I've got this far:
SELECT *
FROM (
SELECT
g.Gender as [Gender],
a.AgeGroup
FROM
client c
INNER JOIN AgeGroup a
ON c.age BETWEEN a.StartRange AND a.EndRange
INNER JOIN Gender G on
C.GenderID = G.GenderID
) as s
PIVOT
(
COUNT(Gender)
FOR [Gender] IN (Male,Female,Transgender,Unknown)
)AS pvt
which returns this:
AgeGroup Male Female Transgender Unknown
<=25 4 0 0 2
26-35 590 413 5 0
>35 6997 2223 43 2
But I don't have the totals.
Is there a way I can do this?
Try this ..
SELECT *,
(select sum(v)
from
(values(male),
(female),
(transgender),
(unknown))
as val(v)) as total
FROM (
SELECT
g.Gender as [Gender],
a.AgeGroup
FROM
client c
INNER JOIN AgeGroup a
ON c.age BETWEEN a.StartRange AND a.EndRange
INNER JOIN Gender G on
C.GenderID = G.GenderID
) as s
PIVOT
(
COUNT(Gender)
FOR [Gender] IN (Male,Female,Transgender,Unknown)
)AS pvt
For updated requirement:
i recommend putting entire table into Some temp table for readabilty and do this
So your above query would go like this
SELECT *,
(select sum(v)
from
(values(male),
(female),
(transgender),
(unknown))
as val(v)) as total
into #temp
from
rest of pivot query
and then do grouping for total
select
case when grouping(agegroup)=1 then 'total' else agegroup end agegroup,
sum(male) as male,
sum(female) as 'female',
sum(trans) as 'trans',
sum(unknown) as 'unknown',
sum(total) as 'Total'
from #temp
group by
grouping sets
(
(agegroup),
()
)

Distinct values with occurrences count

I want to count the number of times a vendor title occurs in a resultset, but if I use COUNT combined with GROUP BY, I only get either a 0 or 1 in the resultset
e.g. my results now look like this:
id vendortitle cnt
184 Hotel 1
198 A3 1
199 Las Vegas 1
200 Hotel-Restaurant 1
1252 Hansen 1
1253 Sunrise 1
1255 NULL 0
1256 Winsel 1
1257 Olde North 1
1258 A Castle 1
1259 A Castle 1
1262 Restaurant Rich 1
1263 NULL 0
1264 NULL 0
1265 NULL 0
1266 NULL 0
1269 My venue 1
1270 My venue 1
1271 My venue 1
1272 My venue 1
But I want this (I don't really actually need the NULL values):
id vendortitle cnt
184 Hotel 1
198 A3 1
199 Las Vegas 1
200 Hotel-Restaurant 1
1252 Hansen 1
1253 Sunrise 1
1255 NULL 5
1256 Winsel 1
1257 Olde North 1
1258 A Castle 2
1262 Restaurant Rich 1
1269 My venue 4
My SQL statement:
SELECT DISTINCT(vendortitle),id,COUNT(vendortitle) as cnt FROM (select ROW_NUMBER() OVER (ORDER BY vendortitle DESC) as RowNum,
id,vendortitle
FROM
(
SELECT
uf.id,coalesce(l.title, a.title) as vendortitle
FROM userfavorites uf
INNER JOIN vendor_photos vp ON uf.objectid = vp.id
LEFT JOIN homes l on vp.objecttype= 1 and vp.objectid = l.id
LEFT JOIN hotels a on vp.objecttype= 2 and vp.objectid = a.id
) as info
) as allinfo
WHERE RowNum > 0 AND RowNum <= 50
GROUP BY vendortitle,RowNum, id
There are a lot of things in your query that you don't need. The derived table isn't really needed, the DISTINCT and ROW_NUMBER either. This should do the work:
SELECT MIN(uf.id) id,
COALESCE(l.title, a.title) as vendortitle,
COUNT(*) as cnt
FROM userfavorites uf
INNER JOIN vendor_photos vp
ON uf.objectid = vp.id
LEFT JOIN homes l
ON vp.objecttype= 1
AND vp.objectid = l.id
LEFT JOIN hotels a
ON vp.objecttype = 2
AND vp.objectid = a.id
GROUP BY COALESCE(l.title, a.title);

Getting records from a table which have non-null values for a particular column in all months

I have a table:
Project_Id Period Value
123 Jan-15 0
123 Feb-15 34
123 Mar-15 78
123 Apr-15 56
456 Jan-15 0
456 Feb-15 0
456 Mar-15 0
456 Apr-15 0
789 Jan-15 45
789 Feb-15 4
789 Mar-15 18
789 Apr-15 26
I need to retrieve Project data only when i do not have 0 for Value field in all the months like:
Project_Id Period Value
123 Jan-15 0
123 Feb-15 34
123 Mar-15 78
123 Apr-15 56
789 Jan-15 45
789 Feb-15 4
789 Mar-15 18
789 Apr-15 26
Project no 456 should not come in my result because for all the months the value is 0 for that particular project.
Can someone help me with the query?
Use SUM and COUNT to determine the number of 0 Values:
SELECT *
FROM tbl
WHERE project_id IN(
SELECT project_id
FROM tbl
GROUP BY project_id
HAVING SUM(CASE WHEN Value = 0 THEN 1 ELSE 0 END) <> COUNT(*)
)
SQL Fiddle
Another solution is to use EXISTS:
SELECT *
FROM tbl t1
WHERE EXISTS(
SELECT 1 FROM tbl t2 WHERE t2.project_id = t1.project_id AND t2.Value > 0
)
SQL Fiddle
The inner select gets all project_ids that have a least one value that is not 0.
select * from your_table
where project_id in
(
select project_id
from your_table
group by project_id
having sum(case when value <> 0 then 1 else 0 end) > 0
)
Some test data but idea remains the same
create table #test123
(
pid int,
value int
)
insert into #test123
select 1,0
union all
select 1,1
union all
select 2,0
union all
select 2,0
union all
select 3,2
select * from #test123 t2 where exists (select 1 from #test123 t1
where t1.pid=t2.pid
group by pid
having sum(value)>0
)
For performance, I prefer not making a join to check for repeating values:
;WITH CTE as
(
SELECT
Project_Id,
Period,
Value,
max(abs(value)) over (Partition by Period) value
FROM YourTable
)
SELECT
Project_Id,
Period,
Value
FROM CTE
WHERE value > 0
*using abs to check for negative values. If all values are positive, the abs can be omitted.

Count from a Count based on a condition in SQL server

I have 4 tables in my database.
Students (Idno, Name, CourseId)
Sample data:
Idno Name CourseId
------------------------
-101123456 Vijay 101
-101123457 John 102
-101123458 Sam 101
-101123459 Arvind 102
-101123460 Smith 101
Courses (CourseId, CourseNo, CourseName, StreamId)
Sample data:
CourseId CourseNo CourseName StreamId
------------------------------------------
-101 53245 C 1
-102 53245 C++ 2
Streams (StreamId, StreamName)
Sample data:
StreamId StreamName
---------------------------
-1 Engineering
-2 Medical
Booking (BId, Idno, BStatus)
Sample data:
Bid Idno BStatus
--------------------------------
-1110 101123456 Confirmed
-1111 101123456 Confirmed
-1112 101123457 Confirmed
-1113 101123458 Confirmed
-1114 101123459 Confirmed
-1115 101123460 Confirmed
-1116 101123456 Confirmed
-1117 101123457 Confirmed
-1118 101123458 Confirmed
-1119 101123459 Confirmed
-1119 101123460 Cancelled
I have a problem generating the following output
SNo Stream BookedOnce BookedTwice NonBooked
1 Engineering 2 3 0
2 Medical 3 1 1
Thanks
I think this requires a two step process. First, calculate the number of bookings by each student for a stream. Then per stream, count the number of students that have one, two or zero bookings.
Here's an example, with the first step in the inner query:
select StreamId
, StreamName
, sum(case when Bookings = 1 then 1 else 0 end) as BookedOnce
, sum(case when Bookings = 2 then 1 else 0 end) as BookedTwice
, sum(case when Bookings = 0 then 1 else 0 end) as NoneBooked
from (
select str.StreamId
, str.StreamName
, s.Idno
, count(b.BId) as Bookings
from Students s
left join
Booking b
on b.Idno = s.Idno
left join
Courses c
on c.CourseId = s.CourseId
left join
Streams str
on str.StreamId = c.StreamId
group by
str.StreamId
, str.StreamName
, s.Idno
) BookingsPerStudentPerStream
group by
StreamId
, StreamName

Combining the rows column values in ASP.NET

SELECT name,
batchno,
recievedeggs,
settingqnty,
CONVERT(VARCHAR(50), settingdate, 103) AS settingdate,
setteroutput,
( 100 * setteroutput / settingqnty ) AS [SetterHatch%],
hathersettingqty,
hatcheroutput,
culls,
[hatcherhatch%],
( 100 * hatcheroutput / Sum(settingqnty) ) AS [Hatch%],
CONVERT(VARCHAR(50), pulloutdate, 103) AS pulloutdate,
hatcher
FROM (SELECT SH.name,
MS.batchno,
MS.recievedeggs,
MS.quantity AS SettingQnty,
MS.settingdate,
SD.remainingqnty AS SetterOutput,
MH.settingqntity AS HatherSettingQty,
MH.saleablechicks AS HatcherOutput,
MH.culls,
Round(MH.hatchpercent, 2) AS [HatcherHatch%],
MH.pulloutdate,
SH1.name AS Hatcher
FROM k_hm_settergetterallocationdet MS
INNER JOIN k_hm_setterdetails SD
ON MS.sno = SD.id
INNER JOIN k_hm_hatcherdetails HD
ON SD.sno = HD.id
INNER JOIN k_hm_masterhatcherdet MH
ON HD.sno = MH.id
INNER JOIN k_hm_gettersetterdet SH
ON MS.name = SH.sno
INNER JOIN k_hm_gettersetterdet SH1
ON HD.hatchername = SH1.sno
WHERE settingdate BETWEEN #fromdate AND #todate)a
GROUP BY a.settingdate,
a.name,
a.recievedeggs,
a.settingdate,
a.setteroutput,
a.hathersettingqty,
a.hatcheroutput
ORDER BY a.settingdate DESC
using this am getting output like:
S.No. SetterName SettingDate FlockNo Rec.Eggs SettingEggs SetterO/P Setter% HatcherName HatcherQnty PulloutDate HatcherO/P Culls Hatcher% Total Hatch%
1 Setter1 01/06/2014 Batch10 2500 2150 2136 99 Hatcher1 2136 22/06/2014 2115 15 99.02 98
2 Setter1 01/06/2014 Batch10 2500 2355 2341 99 Hatcher1 2341 22/06/2014 2314 21 98.85 98
3 Setter2 01/06/2014 Batch10 2450 2255 2241 99 Hatcher1 2241 22/06/2014 2221 20 99.11 98
but I want output like this:
S.No. SetterName SettingDate FlockNo Rec.Eggs SettingEggs SetterO/P Setter% HatcherName HatcherQnty PulloutDate HatcherO/P Culls Hatcher% Total Hatch%
1 Setter1,Setter3 01/06/2014 Batch10 7450 6760 6781 99 Hatcher1 6781 22/06/2014 6650 15 99.02 98
I have tried in this way but it's not correct.
DECLARE #t VARCHAR(Max)
Select #t = ISNULL(#t + ',' + SetterName, SetterName) from hk
where FlockNo in (select FlockNo from hk)
(select #t as setterName,SettingDate,FlockNo,sum(rec) as rec,SUM(SettingEggs)as se,sum([SetterO/P])assop,([Setter%])asse,HatcherName,
Sum(HatcherQnty)HQ,PulloutDate,sum([HatcherO/P]) as hatchero,min(Culls)as culls,max([Hatcher%])as hat,
(Total)
from hk
group by FlockNo,[Setter%],SettingDate,HatcherName,PulloutDate,Total,FlockNo)
getting result
Setter1,Setter2,Setter3 2014-01-06 Batch10 7450 6760 6718 99 Hatcher1 6718 2014-06-22 6650 15 99 98

Resources