To start, I know just enough at this point to get myself into trouble. I am working on writing a query for an AS/400 system. I have a file that contains a start date and end date. What I want to do is create a query that can count how many line items were open for a range of dates. (for my application open is defined as: DATE > START_DATE
AND ( DATE <= END_DATE OR END_DATE = '0'
)). I can get this working for manually setting "DATE", but I'm trying to go back and pull this information in bulk historically. What I'm having trouble with is having it run this query against a list of dates. What I want is to input the historical interval (say CURRENT_DATE - 5
) and output:
Date Open
20200206 30,000
20200207 31,000
20200210 29,675
20200211 31,375
20200212 32,000
What I use for 'one-day-at-a-time' query:
SELECT
COUNT(*)
FROM
MYFILE
WHERE
START_DATE < '20200210'
AND (
END_DATE >= '20200210'
OR END_DATE = '0'
)
This works great, but is time consuming. From here I have no idea how to transition to the desired output...or even if it's possible...but it would speed things up for me. Thanks in advance.
PS any help is welcomed, if you know how to accomplish this in mySQL etc. please share. I can take that and run with it in terms of getting it to work for AS/400 specifically. That is how I've gotten to where I'm at now.
**************** Edit for clarifications 1. Current Code The current-day code provided is all that I have. I don't know where to start on what I am asking for. 2. Example Data:
Line Item START_DATE END_DATE
1 20200206 20200210
2 20200207 20200210
3 20200207 20200207
DATE COUNT
20200205 0
20200206 0
20200207 1
20200210 2
20200211 0
Please try this:
SELECT COUNT(*) FROM MYFILE WHERE (START_DATE < '20200205' AND (END_DATE >= '20200210' OR END_DATE = '0')) GROUP BY DATE_FORMAT(START_DATE , '%Y%m%d')
Sounds like a simple use of the group by
statement, but you don't state which column you're grouping by, just a date, I'll assume START_DATE
I don't know AS/400 SQL so I'm going to be a little bit abstract and assume CURRENT_DATE() returns the current date at your locale. RDBMS' vary in this respect.
Given those assumptions, something like the following should help:
SELECT
START_DATE as DATE,
COUNT(*) as OPEN
FROM
MYFILE
WHERE
START_DATE >= (CURRENT_DATE() - 5)
AND (
END_DATE >= (CURRENT_DATE() - 5)
OR END_DATE = '0'
)
GROUP BY
START_DATE
Unpivot the data and aggregate with window functions. Here is the idea:
with se as (
select dte, sum(ins) as ins, sum(outs) as outs
from ((select start_date as dte, count(*) as ins, 0 as outs
from t
) union all
(select end_date, 0, count(*) as outs
from t
)
)
select dte, ins, outs,
(sum(sum(ins)) over (order by dte) -
sum(sum(outs)) over (order by dte)
)
from se
order by dte;
This adds up all the starts up to a given day and subtracts the number of ends.
Notes:
order by
.end_date
in the subquery. Below is a query returning consecutive dates between given date and given date - 5 days. You may use CURRENT DATE
instead of this constant of course.
WITH T (DT) AS
(
VALUES DATE('2020-02-13') - 5 DAYS
UNION ALL
SELECT DT + 1 DAY
FROM T
WHERE DT < DATE('2020-02-13')
)
SELECT DT FROM T;
The result is:
|DT |
|----------|
|2020-02-08|
|2020-02-09|
|2020-02-10|
|2020-02-11|
|2020-02-12|
|2020-02-13|
Further usage of such a "virtual table" is obvious: you may LEFT JOIN
it with your base table on B.START_DATE < DEC(TO_CHAR(T.DT, 'YYYYMMDD'), 8) AND DEC(TO_CHAR(T.DT, 'YYYYMMDD'), 8) <= B.END_DATE
grouping the result by T.DT
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.