I have a table which says that All students have to take 10 courses, in which 5 are mandatory and choose 3 from other 5. So basically has 2 groups. Now I need to calculate the sum of total Credits and also Sum of group Credits.
Table #1
StudentID ProgID ProgName GroupID GroupName Course Complete_Courses_Alert Credits
1 100 MS 501 Mandatory 12 Remaining 3
1 100 MS 501 Mandatory 13 Complete 3
1 100 MS 501 Mandatory 14 Complete 3
1 100 MS 501 Mandatory 15 Remaining 3
1 100 MS 501 Mandatory 16 Complete 3
1 100 MS 502 Elective 17 Complete 3
1 100 MS 502 Elective 18 Complete 3
1 100 MS 502 Elective 19 Remaining 3
1 100 MS 502 Elective 20 Complete 3
1 100 MS 502 Elective 21 Remaining 3
I want the output as
the above table but with 2 fields more added to it.
i.e. Sum of Completed Credits(Total Credits)
and Sum Complete Credits(By Group)
This is what I have done so far,
I have created a view for calculating total credits and GrouptotalCredits and then joinin it on the main query. This way again i need to create another view to execute more functions on the query..
Can anyone help.
I think you're looking for something like:
select *
, StudentGroupCredits = sum(case when Complete_Courses_Alert = 'Complete' then Credits else 0 end) over (partition by StudentId, GroupName)
, StudentTotalCredits = sum(case when Complete_Courses_Alert = 'Complete' then Credits else 0 end) over (partition by StudentId)
from Courses
SQL Fiddle with demo.
Check out OVER Clause at Books Online for more information.
Related
I am using Big query to extract results from employee learning table. I need to figure out if an employee has completed a set of courses for a department. For example if an employee complete all of these three courses say, course 100, course 200 and course 300, they can be classified as as compliant else They are non-compliant. I have created a dummy example of how my data is structured, unfortunately due to organization policy I cant share more information.
Problem statement.
Say employee who has completed course 100,200,300 They are compliant in Bakery else they are non-complaint. Employee must complete all three courses to be compliant.
Employee who has completed course 100 and 300 They are compliant in Fruit & Veg else they are non-complaint. They must complete above mention two courses to be compliant.
Employee who has completed course 75,85,95 They are compliant in Grocery else non-compliant. Same here they must have done three courses so that they can be compliant.
Employee who has completed 101 and 102 They are compliant in Nighfill else non-compliant.
Please note employee must complete all the sets to be compliant in relevant categories
Employee course
1 100
1 101
1 200
1 300
1 300
1 400
2 100
2 200
3 100
3 200
3 300
4 75
4 85
4 95
4 105
4 115
4 125
5 200
5 200
5 100
5 100
5 100
5 300
5 300
6 100
7 100
8 300
8 200
8 100
8 101
8 102
9 100
9 200
9 300
Structure of Data
I am still thinking about the solution.
Consider below approach
select Employee,
ifnull(array_length(split(string_agg(distinct if(course in (100,200,300), '' || course, null)))), 0) = 3 isBakeyCompliant,
ifnull(array_length(split(string_agg(distinct if(course in (100,300) and not course in (200), '' || course, null)))), 0) = 2 isFruitVegCompliant,
ifnull(array_length(split(string_agg(distinct if(course in (75,85,95), '' || course, null)))), 0) = 3 isGroceryCompliant,
ifnull(array_length(split(string_agg(distinct if(course in (101,102), '' || course, null)))), 0) = 3 isNighfillCompliant,
from your_table
group by Employee
with output
Consider the following table, describing a patients medication plan. For example, the first row describes that the patient with patient_id = 1 is treated from timestamp 0 to 4. At time = 0, the patient has not yet become any medication (kum_amount_start = 0). At time = 4, the patient has received a kumulated amount of 100 units of a certain drug. It can be assumed, that the drug is given in with a constant rate. Regarding the first row, this means that the drug is given with a rate of 25 units/h.
patient_id
starttime [h]
endtime [h]
kum_amount_start
kum_amount_end
1
0
4
0
100
1
4
5
100
300
1
5
15
300
550
1
15
18
550
700
2
0
3
0
150
2
3
6
150
350
2
6
10
350
700
2
10
15
700
1100
2
15
19
1100
1500
I want to add the two columns "kum_amount_start_last_6hr" and "kum_amount_end_last_6hr" that describe the amount that has been given within the last 6 hours of the treatment (for the respective timestamps start, end).
I'm stuck with this problem for a while now.
I tried to tackle it with something like this
SUM(kum_amount) OVER (PARTITION BY patient_id ROWS BETWEEN "dynmaic window size" AND CURRENT ROW)
but I'm not sure whether this is the right approach.
I would be very happy if you could help me out here, thanks!
I need to create 2 cumulative sums based on the value type, for example:
I have values of incoming stock units from 2 types: A and B. and I also have records of outgoing stock units.
If we have enough stock of type "A" it should taken out of type A, if not- it should be taken out of type B. so basically I need to crate the columns "A stock" and "B stock" below, representing the current balance of each type.
I tried using cumulative sum but I'm having trouble with the condition... is there a way to write this query without using a loop ? ( Vertica DB)
In table below A_stock and B_stock are the final result I need to create
ID Type In OUT A stock B stock Order_id
1 A 100 0 100 0 1
1 B 50 0 100 50 2
1 A 100 0 200 50 3
1 - 0 -200 0 50 4
1 - 0 -10 0 40 5
1 B 50 0 0 90 6
1 A 40 0 40 90 7
1 - 0 -20 20 90 8
2 A 30 0 30 0 1
2 B 20 0 30 20 2
2 A 10 0 40 20 3
2 - 0 -20 20 20 4
You can use window functions - but you need a column that defines the ordering of the rows, I assumed ordering_id:
select t.*,
sum(case when type = 'A' then in + out else 0 end) over(partition by id order by ordering_id) a_stock,
sum(case when type = 'B' then in + out else 0 end) over(partition by id order by ordering_id) b_stock
from mytable t
This assumes that you want the stock on a per-id basis; if that's not the case, just remove the partition clause from the over() clause.
Using SQL Management studio 2012
I have a query similar to below but need to add the percentage column of the pass rate
SELECT
pass,
fail,
total,
name
FROM table
pass fail total name %
3 1 4 Joe 75
5 0 5 Matt 100
1 1 2 Al 50
7 0 7 Freda 100
What I've tried to get the result:
SELECT
name,
sum(pass) /Sum(total) *100.0 as pass_rate
FROM
(
SELECT
pass,
fail,
total,
name
FROM table
)a
GROUP BY name
Result obtained when running above query(which is wrong):
name pass_rate
Joe 100
Matt 100
Al 0
Freda 100
Please help. Thankyou.
Just move that Multiply by 100 inside to numerator
SELECT
name,
SUM(pass) * 100 /Sum(total) AS pass_rate
....
You can try below
DEMO
select
pass,
fail,
total,
name,(pass*1.0/total)*100 as pass_rate
from table
OUTPUT:
pass fail total name pass_rate
3 1 4 Joe 75.0
5 0 5 Matt 100.0
1 1 2 Al 50.0
7 0 7 Freda 100.0
I am trying to change something like this:
Index Record Time
1 10 100
1 10 200
1 10 300
1 10 400
1 3 500
1 10 600
1 10 700
2 10 800
2 10 900
2 10 1000
3 5 1100
3 5 1200
3 5 1300
into this:
Index CountSeq Record LastTime
1 4 10 400
1 1 3 500
1 2 10 700
2 3 10 1000
3 3 5 1300
I am trying to apply this logic per unique index -- I just included three indexes to show the outcome.
So for a given index I want to combine them by streaks of the same Record. So notice that the first four entries for Index 1 have Records 10, but it is more succinct to say that there were 4 entries with record 10, ending at time 400. Then I repeat the process going forward, in sequence.
In short I am trying to perform a count-grouping over sequential chunks of the same Record, within each index. In other words I am NOT looking for this:
select index, count(*) as countseq, record, max(time) as lasttime
from Table1
group by index,record
Which combines everything by the same record whereas I want them to be separated by sequence breaks.
Is there a way to do this in SQL?
It's hard to solve your problem without having a single primary key, so I'll assume you have a primary key column that increases each row (primkey). This request would return the same table with a 'diff' column that has value 1 if the previous primkey row has the same index and record as the current one, 0 otherwise :
SELECT *,
IF((SELECT index, record FROM yourTable p2 WHERE p1.primkey = p2.primkey)
= (SELECT index, record FROM yourTable p2 WHERE p1.primkey-1 = p2.primkey), 1, 0) as diff
FROM yourTable p1
If you use a temporary variable that increases each time the IF expression is false, you would get a result like this :
primkey Index Record Time diff
1 1 10 100 1
2 1 10 200 1
3 1 10 300 1
4 1 10 400 1
5 1 3 500 2
6 1 10 600 3
7 1 10 700 3
8 2 10 800 4
9 2 10 900 4
10 2 10 1000 4
11 3 5 1100 5
12 3 5 1200 5
13 3 5 1300 5
Which would solve your problem, you would just add 'diff' to the group by clause.
Unfortunately I can't test it on sqlite, but you should be able to use variables like this.
It's probably a dirty workaround but I couldn't find any better way, hope it helps.