I have a table with the following data:
Class Student Score Date
A Tom 10 Aug 1
B Dave 9 Aug 1
A Jan 7 Aug 2
B Jack 8 Aug 2
A Matt 5 Aug 3
B Dave 8 Aug 4
A Matt 8 Aug 4
Each student can only have one score in each day but can have multiple scores for multiple days.
I want to do a query to list total score of each class and number of student in each class. How can I do that with one query?
The expected result:
Class Student_Count Total_Score
A 3 30
B 2 25
You need to group by class, count the distinct number of students and sum the scores of all the students:
SELECT Class,
COUNT(DISTINCT Student) Student_Count,
SUM(Score) Total_Score
FROM tablename
GROUP BY Class;
See the demo.
Use a distinct student count:
SELECT Class,
COUNT(DISTINCT Student) AS Student_Count,
SUM(Score) AS Total_Score
FROM yourTable
GROUP BY
Class;
I've searched but can't find the right answer, and I'm going round in circles.
I have
CREATE TABLE History (yr Int, output Int, cat Text);
yr output cat
---------- ---------- ----------
2015 10 a
2016 20 a
2017 30 a
2018 50 a
2019 70 a
2015 100 b
2016 200 b
2017 300 b
2018 500 b
2019 700 b
2015 1000 c
2016 2000 c
2017 3000 c
2018 5000 c
2019 7000 c
2015 10000 d
2016 20000 d
2017 30000 d
2018 50000 d
2019 70000 d
I've created two views
CREATE VIEW Core AS select * from History where cat = "c" or cat = "d";
CREATE VIEW Plus AS select * from History where cat = "a" or cat = "b";
My query is
select distinct yr, sum(output), (select sum(output) from core group by yr) as _core, (select sum(output) from plus group by yr) as _plus from history group by yr;
yr sum(output) _core _plus
---------- ----------- ---------- ----------
2015 11110 11000 110
2016 22220 11000 110
2017 33330 11000 110
2018 55550 11000 110
2019 77770 11000 110
Each of the individual queries works but _core and _plus columns are wrong when it's all put together. How should I approach this please.
You may generate your expected output without a view, using a single query with conditional aggregation:
SELECT
yr,
SUM(output) AS sum_output,
SUM(CASE WHEN cat IN ('c', 'd') THEN output ELSE 0 END) AS _core,
SUM(CASE WHEN cat IN ('a', 'b') THEN output ELSE 0 END) AS _plus
FROM History
GROUP BY
yr;
If you really wanted to make your current approach work, one way would be to just join the two views by year. But that would leave open the possibility that each view might not have every year present.
is there any way in Oracle that My month start after every 28 days
Example
24-dec- 2015 to 20-jan-16 ( we mention Dec 2015)
21-jan-16 to 17-feb-16 (we mention Jan 16)
select rownum as month_number
,day1 + (rownum-1) * 28 as gregorian_month_start
,day1 + rownum * 28 - 1 as gregorian_month_end
from (select date'2015-12-24' day1
from dual connect by level <= 13);
1 24/DEC/2015 20/JAN/2016
2 21/JAN/2016 17/FEB/2016
3 18/FEB/2016 16/MAR/2016
4 17/MAR/2016 13/APR/2016
5 14/APR/2016 11/MAY/2016
6 12/MAY/2016 08/JUN/2016
7 09/JUN/2016 06/JUL/2016
8 07/JUL/2016 03/AUG/2016
9 04/AUG/2016 31/AUG/2016
10 01/SEP/2016 28/SEP/2016
11 29/SEP/2016 26/OCT/2016
12 27/OCT/2016 23/NOV/2016
13 24/NOV/2016 21/DEC/2016
Note: this doesn't handle the 365th day for normal years, or 366th day for leap years. You would need to specify which month these should be added to.
I have two tables say A ( Detail table) and B (summary table).
Transactions in table A fall into various months within a year. Table B has some fields defined to correspond to a particular month (as illustrated below). I want a procedure that will fetch records from Table A and update Table B such that the amounts for say month 1 will be summed up in YTDBAL_1, month 2 will be the sum of month 1 plus sum of month 2 (YTDBAL2) and so on such that the consecutive month will hold cumulative balances from beginning of year to date (current month).
Sample Data in Table A
OFFCD GLHEAD YEAR MONTH AMOUNT
010 10101001 2014 01 25,000.00
010 10101001 2014 01 5,000.00
010 10101001 2014 02 8,000.00
010 10101001 2014 02 4,000.00
010 10101001 2014 03 10,000.00
010 10101001 2014 04 10,000.00
010 10101001 2014 05 -4,000.00
010 10101001 2014 05 3,000.00
..
..
010 10101001 2014 12 1,000.00
Expected data in Table B
OFFCD GLHEAD YEAR YTDBAL_1 YTDBAL_2 YTDBAL_3 YTDBAL_4 YTDBAL_5 ..... YTDBAL_12
010 10101001 2014 30,000 42,000 52,000 62,000 61,000 XXX
My procedure below was populating all fields with same amount. How do i make it such that i arrive at above expected result.
NB: The transaction table has more than a million records and I am using Oracle 11g.
CREATE OR REPLACE PROCEDURE rectify_gl_bal(w_year Number)
IS
CURSOR gl_cur IS
Select * from nlmstdtl
where period_year=w_year;
TYPE gl_array IS TABLE OF gl_cur%ROWTYPE;
gldtl gl_array;
Begin
open gl_cur;
Loop
Fetch gl_cur bulk collect into gldtl limit 500;
EXIT WHEN gldtl.count = 0;
Forall x in 1..gldtl.count
update nlmst
set NLMST.YTDBAL_1 = NLMST.YTDBAL_1 + gldtl(x).amount,
NLMST.YTDBAL_2 = NLMST.YTDBAL_2 + gldtl(x).amount,
NLMST.YTDBAL_3 = NLMST.YTDBAL_3 + gldtl(x).amount,
NLMST.YTDBAL_4 = NLMST.YTDBAL_4 + gldtl(x).amount,
NLMST.YTDBAL_5 = NLMST.YTDBAL_5 + gldtl(x).amount,
NLMST.YTDBAL_6 = NLMST.YTDBAL_6 + gldtl(x).amount,
NLMST.YTDBAL_7 = NLMST.YTDBAL_7 + gldtl(x).amount,
NLMST.YTDBAL_8 = NLMST.YTDBAL_8 + gldtl(x).amount,
NLMST.YTDBAL_9 = NLMST.YTDBAL_9 + gldtl(x).amount,
NLMST.YTDBAL_10 = NLMST.YTDBAL_10 + gldtl(x).amount,
NLMST.YTDBAL_11 = NLMST.YTDBAL_11 + gldtl(x).amount,
NLMST.YTDBAL_12 = NLMST.YTDBAL_12 + gldtl(x).amount
where nlmst.offcd = gldtl(x).offcd and
nlmst.period_year = gldtl(x).period_year and
nlmst.glhead = gldtl(x).glhead;
End Loop;
commit;
close gl_cur;
End;
It it really required to write a procedure? Can't something like that do the trick:
SELECT OFFCD, GLHEAD, YEAR,
SUM(CASE WHEN MONTH <= 01 THEN AMOUNT ELSE 0 END) YTDBAL_1,
SUM(CASE WHEN MONTH <= 02 THEN AMOUNT ELSE 0 END) YTDBAL_2,
SUM(CASE WHEN MONTH <= 03 THEN AMOUNT ELSE 0 END) YTDBAL_3,
SUM(CASE WHEN MONTH <= 04 THEN AMOUNT ELSE 0 END) YTDBAL_4,
SUM(CASE WHEN MONTH <= 05 THEN AMOUNT ELSE 0 END) YTDBAL_5
-- and so on up to YTDBAL_12
-- ...
FROM A
GROUP BY OFFCD, GLHEAD, YEAR
Producing (given the first 8 rows of your sample data):
OFFCD GLHEAD YEAR YTDBAL_1 YTDBAL_2 YTDBAL_3 YTDBAL_4 YTDBAL_5
10 10101001 2014 30000 42000 52000 62000 61000
I need some help to build SQL Query. I have table having data like:
ID Date Value1 Value2 Code
1 12/01/2009 4 3.5 abc
2 12/02/2009 3 4.0 abc
3 11/03/2009 6 8.5 xyz
4 11/01/2009 2 5.5 abc
5 11/02/2009 4 6.0 xyz
6 12/03/2009 5 7.0 xyz
I need to show result something like...
---------
Code | Data | November(Sum of Values in month) December Jan Feb
abc | Value1 | 2 7 0 0
| Value2 | 5 7 0 0
xyz | Value1 | 10 5 0 0
| Value2 | 14 7 0 0
----------
I need sum of value in each month as in above data in columns group by code.
Have a look at this solution, and let me know what you think.
You have to use both PIVOT and UNPIVOT in this instance to get the result you are looking for. Hope this helps.
DECLARE #Table TABLE(
ID INT,
Date DATETIME,
Value1 INT,
Value2 FLOAT,
Code VARCHAR(10)
)
INSERT INTO #Table (ID,Date,Value1,Value2,Code) SELECT 1,'12/01/2009',4,3,'abc'
INSERT INTO #Table (ID,Date,Value1,Value2,Code) SELECT 2,'12/02/2009',3,4,'abc'
INSERT INTO #Table (ID,Date,Value1,Value2,Code) SELECT 3,'11/03/2009',6,8,'xyz'
INSERT INTO #Table (ID,Date,Value1,Value2,Code) SELECT 4,'11/01/2009',2,5,'abc'
INSERT INTO #Table (ID,Date,Value1,Value2,Code) SELECT 5,'11/02/2009',4,6,'xyz'
INSERT INTO #Table (ID,Date,Value1,Value2,Code) SELECT 6,'12/03/2009',5,7,'xyz'
;WITH UnPvt AS (
SELECT *
FROM (
SELECT Code,
DATENAME(MM, Date) MonthNameVal,
SUM(Value1) Value1,
SUM(Value2) Value2
FROM (
SELECT Code,
Date,
CAST(Value1 AS FLOAT) Value1,
Value2
FROM #Table
) v
GROUP BY Code,
DATENAME(MM, Date)
) Sub
UNPIVOT
(
Vals FOR RowValues IN (Value1, Value2)
) AS UnPvt
)
SELECT *
FROM UnPvt
PIVOT (
SUM(Vals)
FOR MonthNameVal IN ([January],[February],[March],[April],[May],[June],[July],[August],[September],[October],[November], [December])
) AS pvt
ORDER BY Code, RowValues
Have a look at
SQL SERVER – PIVOT and UNPIVOT Table
Examples
Give the New PIVOT and UNPIVOT
Commands in SQL Server 2005 a
Whirl
Using PIVOT and UNPIVOT
This isn't quite what you asked for because the number of columns is fixed, but I think it's a better way to what you want in SQL:
SELECT Code, 'Value1' As Data, MONTH(Date) AS Month, YEAR(Date) AS Year, SUM(Value1) AS Sum
FROM Table1
GROUP BY Code, MONTH(Date), YEAR(Date)
UNION ALL
SELECT Code, 'Value2' As Data, MONTH(Date) AS Month, YEAR(Date) AS Year, SUM(Value2) AS Sum
FROM Table1
GROUP BY Code, MONTH(Date), YEAR(Date)
ORDER BY Code, Data, Month, Year
Example output:
Code Data Month Year Sum
abc Value1 11 2009 2
abc Value1 12 2009 7
abc Value2 11 2009 5
abc Value2 12 2009 7
xyz Value1 11 2009 10
xyz Value1 12 2009 5
xyz Value2 11 2009 14
xyz Value2 12 2009 7
I'd recommend that you use a bit of non-SQL code to reformat the result into exactly what you asked for before displaying it to the user rather than trying to return a variable number of columns in SQL.