I have set of jobs record for whole month and want to display qty of jobs date wise in SQL - sql

We have thousands of record in our data and want to count date wise jobs with category through single query. It is Possible?
Display required as under
TypesJobs 01 02 03 04 05 06 07
A 2 1 6 4 1 3 4
B 10 12 8 10 12 9 13
C 3 5 4 3 2 5 4
Here Types of jobs count for a day in date column 01, 02, 03 are date range of the month

You can use conditional aggregation, something like this:
select typesjobs,
sum(case when month(datecol) = 1 then 1 els e0 end) as month_01,
sum(case when month(datecol) = 2 then 1 els e0 end) as month_02,
. . .
from t
where <date condition here>
group by typesjobs;

Related

SQL Method to report next period value for this period

This may already be answered, but I can't figure out the correct search terms for what I need. We store values by Year / Period for the Beginning of Month (BOM). The BOM for one month is the same value as End of Month (EOM) for the previous month. I need a way to report this as such.
So 2018-02 BOM = 2018-01 EOM.
I thought I might be able to use something simple, but it does not account for the month/year wrap at 12 months as those fields are numerical.
select yr as YEAR, (pd-1) as PERIOD, sum(BOM) as EOM
from Table1
where type = '3'
group by yr, pd
order by yr desc, pd desc
This works for the middle months, but not for January, which becomes 2018-0 instead of 2017-12.
Example Data
Yr Pd Type BOM
18 02 3 100
18 02 3 100
18 02 2 200
18 02 2 100
18 01 3 100
18 01 3 100
18 01 2 200
18 01 2 100
18 01 3 100
18 01 2 300
17 12 3 100
17 12 3 200
17 12 2 300
17 12 3 200
17 12 2 100
17 11 3 300
17 11 2 400
17 11 3 400
17 11 2 100
So the results I am looking for would be:
Yr Pd EOM
18 01 200
17 12 300
17 11 500
17 10 700
I'm working in System iNavigator currently, but hoping to move this into an externally connected Excel query at some point.
Your DB2 database should be able to use CASE WHEN
Which can be used to calculate the year and the month, depending on the month.
For example:
select
CASE WHEN pd = 1 THEN yr - 1 ELSE yr END as Yr,
CASE WHEN pd = 1 THEN 12 ELSE pd - 1 END as Pd,
SUM(BOM) as EOM
from Table1
where type = '3'
group by yr, pd
order by yr desc, pd desc

Adding rows, running count, running sum to query results

I have a table with the following ddl.
CREATE TABLE "LEDGER"
("FY" NUMBER,
"FP" VARCHAR2(20 BYTE),
"FUND" VARCHAR2(20 BYTE),
"TYPE" VARCHAR2(2 BYTE),
"AMT" NUMBER
)
The table contains the following data.
REM INSERTING into LEDGER
SET DEFINE OFF;
Insert into LEDGER (FY,FP,FUND,TYPE,AMT) values (15,'03','A','03',1);
Insert into LEDGER (FY,FP,FUND,TYPE,AMT) values (15,'04','A','03',2);
Insert into LEDGER (FY,FP,FUND,TYPE,AMT) values (16,'04','A','03',3);
Insert into LEDGER (FY,FP,FUND,TYPE,AMT) values (12,'05','A','04',6);
based on the partition of fy,fp,fund and type I would like to write a query to keep a running count from the beginning of fp(fp though it is a varchar it represents a number in the month. i.E 2 equals february and 3 equals march etc.) to a hard number of 14. So taking a closer look at the data you will notice that in FY 15 the max period is 04 so i must add another 10 periods to my report to get my report to have the full 14 periods. here is the expected output.
here is what i tried, but I'm just simply stumbling all together on this.
WITH fy_range AS
(
SELECT MIN (fy) AS min_fy
, MAX (fy) AS max_fy
FROM ledger
),all_fys AS
(
SELECT min_fy + LEVEL - 1 AS fy
FROM fy_range
CONNECT BY LEVEL <= max_fy + 1 - min_fy
)
,all_fps AS
(
SELECT TO_CHAR (LEVEL, 'FM00') AS fp
FROM dual
CONNECT BY LEVEL <= 14
)
SELECT
FUND
,G.TYPE
,G.FY
,G.FP
,LAST_VALUE(G.AMT ignore nulls) OVER (PARTITION BY G.FUND ORDER BY Y.FY P.FP ) AS AMT
FROM all_fys y
CROSS JOIN all_fps p
LEFT OUTER JOIN LEDGER G PARTITION BY(FUND)
ON g.fy = y.fy
AND g.fp = p.fp;
but I end up with a bunch of nulls and some strange results.
This may not be the most efficient solution, but it is easy to understand and maintain. First (in the most deeply nested subquery) we find the min FP for each combination of FY, FUND and TYPE. Then we use a CONNECT BY query to fill all the FP for all FY, FUND, TYPE combinations (up to the hard upper limit of 14). Then we left-outer-join to the original data in the LEDGER table. So far we densified the data. In the final query (the join) we also add the column for the cumulative sum - that part is easy after we densified the data.
TYPE is an Oracle keyword, so it is probably best not to use it as a column name. It is also best not to use double-quoted table and column names (I had to use upper case everywhere because of that). I also made sure to convert from varchar2 to number and back to varchar2 - we shouldn't rely on implicit conversions.
select S.FY, to_char(S.FP, 'FM09') as FP, S.FUND, S.TYPE,
sum(L.AMT) over (partition by S.FY, S.FUND, S.TYPE order by S.FP) as CUMULATIVE_AMT
from (
select FY, MIN_FP + level - 1 as FP, FUND, TYPE
from (
select FY, min(to_number(FP)) as MIN_FP, FUND, TYPE
from LEDGER
group by FY, FUND, TYPE
)
connect by level <= 15 - MIN_FP
and prior FY = FY
and prior FUND = FUND
and prior TYPE = TYPE
and prior sys_guid() is not null
) S left outer join LEDGER L
on S.FY = L.FY and S.FP = L.FP and S.FUND = L.FUND and S.TYPE = L.TYPE
;
Output:
FY FP FUND TYPE CUMULATIVE_AMT
--- --- ---- ---- --------------
12 05 A 04 6
12 06 A 04 6
12 07 A 04 6
12 08 A 04 6
12 09 A 04 6
12 10 A 04 6
12 11 A 04 6
12 12 A 04 6
12 13 A 04 6
12 14 A 04 6
15 03 A 03 1
15 04 A 03 3
15 05 A 03 3
15 06 A 03 3
15 07 A 03 3
15 08 A 03 3
15 09 A 03 3
15 10 A 03 3
15 11 A 03 3
15 12 A 03 3
15 13 A 03 3
15 14 A 03 3
16 04 A 03 3
16 05 A 03 3
16 06 A 03 3
16 07 A 03 3
16 08 A 03 3
16 09 A 03 3
16 10 A 03 3
16 11 A 03 3
16 12 A 03 3
16 13 A 03 3
16 14 A 03 3

Crosstab with static column

How can I make a static column/row in crosstab? See example below; can I have a fixed jan, feb, march, ... columns instead of it generating dynamically?
location jan feb mar apr may jun jul aug sep oct nov dec
london 500 62 200 50 0 60 100 46 89 200 150 210
paris 50 26 20 500 50 70 40 200 0 40 250 50
I want the column (jan, feb, mar, apr, ...) to always show up regardless of their measures zero or have values. Like they are fixed.
Here is the query I'm using:
select sum("AMOUNT"), "REQUESTDATE","description"
from(
SELECT SUM(e.AMOUNT)"AMOUNT",TO_CHAR(REQUESTDATE,'MM')"REQUESTDATE", CA.DESCR "description"
FROM PC_PAYMENTTRXNLOG PC,GLB_TYPE ca, PC_ESERVICEINQUIRY e
where PC.ESERVICE_ID = E.ID
AND trunc(REQUESTDATE) between trunc(to_date('2012-01-01','yyyy-mm-dd')) and trunc(to_date('2012-06-30','yyyy-mm-dd'))
GROUP BY TO_CHAR(REQUESTDATE,'MM'),CA.DESCR
)
group by "REQUESTDATE","description"
and the output
SUM("amount") Requestdate Description
2550405 04 A
2550405 04 B
23893281 05 C
614977 06 A
614977 06 E
2550405 04 C
now after updated the query to be
select sum("AMOUNT"), month,"description"
from(
SELECT SUM(e.AMOUNT)"AMOUNT",TO_CHAR(REQUESTDATE,'MM')"REQUESTDATE", CA.DESCR "description"
FROM PC_PAYMENTTRXNLOG PC,GLB_TYPE ca, PC_ESERVICEINQUIRY e
where PC.ESERVICE_ID = E.ID
AND trunc(REQUESTDATE) between trunc(to_date('2012-01-01','yyyy-mm-dd')) and trunc(to_date('2012-06-30','yyyy-mm-dd'))
GROUP BY TO_CHAR(REQUESTDATE,'MM'),CA.DESCR
)
full outer join (select to_char(date '1970-01-01'
+ numtoyminterval(level - 1, 'month'), 'mm') as month
from dual
connect by level <= 12) on month="REQUESTDATE"
group by month,"description"
when run the query run it displaying all the months regardless of their measures zero or have values.
BUT now the output is like that
location jan feb mar apr may jun jul aug sep oct nov dec
london 500 62 200 50 0 60 100 46 89 200 150 210
paris 50 26 20 500 50 70 40 200 0 40 250 50
null 0 0 0 0 0 0 0 0 0 0 0 0
how i can restrict/hide the last null row?
have not tested it.. but try something like this
select sum("AMOUNT"), month,"description"
from(SELECT SUM(e.AMOUNT)"AMOUNT",TO_CHAR(REQUESTDATE,'MM')"REQUESTDATE", CA.DESCR "description"
FROM PC_PAYMENTTRXNLOG PC,GLB_TYPE ca, PC_ESERVICEINQUIRY e
where PC.ESERVICE_ID = E.ID
AND trunc(REQUESTDATE) between trunc(to_date('2012-01-01','yyyy-mm-dd')) and trunc(to_date('2012-06-30','yyyy-mm-dd'))
GROUP BY TO_CHAR(REQUESTDATE,'MM'),CA.DESCR
)
full outer join (select to_char(date '1970-01-01'
+ numtoyminterval(level - 1, 'month'), 'mm') as month
from dual
connect by level <= 12) on month="REQUESTDATE"
group by month,"description"
click here for SQL Fiddle demo to generate 1 to 12 in Oracle
Once you have generated this.. full outer join Your main query with this series query and take month from series query as I did in main query.
Using this query you will get all the data for all months with null values in measure.
For Description column - iReport set property's isRemoveLineWhenBlank and isBlankWhenNull to True, This will remove the null value being printed in iReport
For Measure use Print when expression in such a way, when ever description is null then return false. So this will prevent the value 0 being printed in iReport.

SQL: how to select IDs according to a condition?

I just started to program in SQL and I have a bit of a problem (n.b., I am working of a tabl that come from a game). My table is something like this, where ID refers to a single person, H to a certain hour of playing and IF to a certain condition:
ID H IF
01 1 0
01 2 0
01 3 0
02 1 0
02 2 1
03 1 0
03 2 1
03 3 0
03 4 1
In this case player 01 played for three hours, player 02 for two hours and player 03 for four hours. In each of these hours they may or may have not performed an action. If they did, a 1 appears in the IF column.
Now, my doubt is: how can I query so that I have a table with only the ID of the people who never performed the action? I do not want to rule out only the row with IF = 1, I want to rule out all the row with that ID. In this case it should become:
01 1 0
01 2 0
01 3 0
Any help?
This should do it.
select *
from table
where Id not in (select Id from table where IF = 1)
SELECT ID FROM Table GROUP BY ID HAVING SUM(IF)=0

SQLite: Group records with nearest integer field

There is a table with integer field. I need to write a query which returns groups with the following condition: min value of the field in the some group differs more than N to max value in the next group.
Example with N=10.
SQL query for the table
01 A A 1
02 A B 9
03 B B 11
04 B C 22
05 C C 29
should return
01 A A 1 0
02 A B 9 0
03 B B 11 0
04 B C 22 1
05 C C 29 1
Here is a similar question for Python. How to do this in SQLite?