I have a simple query to pull DAYOFWEEK from SYSIBM/SYSDUMMY1 to determine whether or not to clear a table that tracks yesterday sales.
DELETE FROM DAILYSALES WHERE (CASE WHEN (SELECT DAYOFWEEK(CURRENT DATE)
FROM SYSIBM/SYSDUMMY1)
BETWEEN 3 AND 6 THEN 'YES' ELSE 'NO' END) = 'YES';
Since the report that runs on Monday (dayofweek=2) needs Friday (dayofweek=6), Saturday (dayofweek=7), Sunday (dayofweek=1) sales (today-1 to calculate date), it would seem logical that I should see sales figures for days 6, 7, and 1.
However, it seems to be retaining Thursday's (dayofweek=5) sales and not pulling Sunday sales (dayofweek=1) when it runs on Monday morning. This leads me to believe the date being used by SYSDUMMY1 doesn't flip until long after midnight, even though our system date flips at midnight EST.
It runs fine the rest of the week, providing the correct sales data for 'yesterday'. When I manually run Select DAYOFWEEK(current date) from SYSIBM.SYSDUMMY1, it always shows the correct dayofweek. What am I missing?
I don't see any correlation (usage) of a column in DAILYSALES..
Thus
(CASE WHEN (SELECT DAYOFWEEK(CURRENT DATE)
FROM SYSIBM/SYSDUMMY1)
BETWEEN 3 AND 6 THEN 'YES' ELSE 'NO' END)
Is only evaluated one time and if the process runs on Monday, would return 2==>NO so no rows would be deleted.
I suspect instead of DAYOFWEEK(CURRENT DATE) you want DAYOFWEEK(SALESDATE) where SALESDATE is a column in the DAILYSALES table.
Lastly note that SYSIBM.SYSDUMMY1 has only a single char(1) column IBMREQ and a single row with the value of that column set to 'Y'. Nothing is ever updated in this table.
Related
SELECT (outbound.data_bas_year||outbound.data_bas_month) as year,
EXTRACT(QUARTER from to_date(outbound.data_bas_year||outbound.data_bas_month, 'YYYYMM')) AS quarter,
count(outbound.call_time) as col_1_0_
FROM cfk_dashboard.if_outbnd_call_dtl outbound
WHERE outbound.data_bas_year||outbound.data_bas_month between '20210101' and '20211231'
AND outbound.conn_call_number = 1
GROUP BY year,quarter
I wrote a query to look up January through December quarterly, but no data for January is aggregated.
In other words, only February and March are counted except for January in the first quarter.
However, if I change the condition start date from 20210101 to 20201231, I get the result I want.
Why?
Function to_date generates date for you, if you have not day value then default value of day will be -01.
But in your query after command WHERE you are used outbound.data_bas_year||outbound.data_bas_month, this is gets only 202101 and you compare this with 20211231 or with 20210101, this will not work correctly. For example, you can use outbound.data_bas_year||outbound.data_bas_month||'01' or to_date(outbound.data_bas_year||outbound.data_bas_month, 'YYYYMM') between '20210101'::date and '20211231'::date
I want to get the whole day of the week depend on the date, my query is working and getting the result that I want but when the date value is Sunday, result changes.
I'm starting the result from Mon to Sunday.
Examples below:
My Code:
SELECT UserID,Scdl_TkIN as TimeIn, Scdl_TkOut as [TimeOut]
FROM EmployeeTimekeeping
WHERE CONVERT(DATE,Scdl_TkIN) >= dateadd(day, 2-datepart(dw, '2022-04-23'),CONVERT(date,'2022-04-23'))
AND CONVERT(DATE,Scdl_TkIN) < dateadd(day, 9-datepart(dw, '2022-04-23'), CONVERT(date,'2022-04-23'))AND UserID ='15020009'
ORDER BY CONVERT(DATE,Scdl_TkIN)
1st display is correct, but when I change the value into '2022-04-24' , the result is now the second pic but I want the result still 1st pic.
If I got it right you want the whole week of data given a single date.
I'm not 100% sure about your date logic and I'd rather use the WEEK as a filter as it seems clearer, that said the issue you have is the value of SELECT ##DATEFIRST.
By default its value is 7, meaning that Sunday is considered the first day of the week, that's why you get that "unexpected" result.
here is my solution, but just setting SET DATEFIRST 1; should give you the expected result.
SET DATEFIRST 1;
SELECT
UserID
,Scdl_TkIN as TimeIn
,Scdl_TkOut as TimeOut
FROM EmployeeTimekeeping
WHERE
DATEPART(WEEK,Scdl_TkIN) = DATEPART(WEEK,'2022-04-23')
AND YEAR(Scdl_TkIN) = YEAR('2022-04-23')
AND UserID ='15020009'
ORDER BY
Scdl_TkIN
Note: if you decide to use WEEK for filtering you will have to choose between WEEK and ISO_WEEK
Edit: when using week you must also consider the year in the filter
Can anyone help me to find the specific week day of the month in postgresql... like 1st and 3rd week sunday/monday or 2nd and 4th week wednesday
First off contrary to initial expectations working with dates is complex, sometime extremely so. The combination of week numbers and days the week fall into the latter category.
The problem stems from the 2 ISO definitions:
All weeks start on Monday and are 7 days long.
The first week of the year is the week containing 4-Jan.
This dooms any effort (at least any reasonable simple onc) to failure. While an admirable effort I'll use #Abelisto suggestion as a sample. See Fiddle. I've changed that just enough to use multiple parameters, while for most months it's correct but look at 30,31-Jan-2019 and Jan-2021.
The problem with the first being while the ISO week is perfectly consistent the calendar is not. This results that the first week of a given month be the same as the last week of the previous month, and the reverse.
While this can usually be worked around by itself not so when combined with the other. As a result of each being 7 days long and the 1st week of the year containing 4-Jan gives rise to the larger problem. The last few days of Dec maybe in the 1st week of the next year. Also the first days of Jan can be in the 52( or 53) week of the prior year (see 2nd query in fiddle). Is there a solution? I'm sure there is somewhere out there. I just don't have it. At least with the Extract function.
So how about this specific issue: Well basically it comes down to getting the last day of the previous month, then finding the next DOW (Sunday or Monday) as needed. Now coming from a Oracle back ground I'd just use the NEXT_DAY function which would do just that for me. Unfortunately Postgres does not provide that useful function. But you can roll your own. Below I provide a a couple functions I wrote to do this functionality in Postgres. It consists of 2 Postgres SQL functions:
- utl_dates_first_dow_of_month(). It takes 2 parameters, the target Day-Of-Week (DOW) as the first 3 characters of the day name (case insensitive) and a date in the desired month. It returns the DATE which is the first occurrence of the requested DOW.
- utl_dates_next_dow(). It takes the same 2 parameters and returns the next calendar date of the specified DOW from the from the specified date. If the date specified fall on the requested DOW the routine DOES NOT return the specified date. Function is actually used by the first.
Fortunately the routines are shorter than the description.
create or replace function utl_dates_next_dow(dow_in text, date_in date)
returns date
language sql
immutable strict
as $$
-- Given a DOW and a date return the calendar date for the next occurrence of DOW
with dy as (select string_to_array('mon,tue,wed,thu,fri,sat,sun', ',') dl)
, dn as (select array_position(dl, (substring(to_char(date_in, 'day'),1,3))) fn
, array_position(dl, lower(substring(dow_in,1,3))) dn
from dy
)
select case when dn <= fn
then (date_in + (dn+7-fn) * interval '1 day')::date
else (date_in + (dn-fn) * interval '1 day')::date
end
from dn;
$$;
create or replace function utl_dates_first_dow_of_month(dow_in text, date_in date)
returns date
language sql
immutable strict
as $$
-- Given a DOW and a Date return the calendar date of the first specified dow in which the specified date falls.
select utl_dates_next_dow(dow_in, (date_trunc('month', date_in) - interval '1 day')::date);
$$;
Now with that out out of the way on the the issue at hand. As Abelisto, and others, indicate the request is ambiguous. There is no such thing as 1st or 3rd Sunday/Monday. Do you want the 1st and 3rd Sunday and the 1st and 3rd Monday of the month? Do you want
Do you want the 1st and 3rd Sunday of the month and the Monday following each respectively. Do you want the Sunday and Monday for the 1st and 3rd week on the month (If so Monday would always be the earlier date, see definition 1 above)? Please try to be more specific with your questions. And include test data - as text no images - and the expected results from that data. The solutions are however just slight modifications of each other. (No solution for the 3rd listed possibility.)
For the case of 1st and 3rd Sunday and the 1st and 3rd Monday:
with parms (dt) as (values ( date '2020-04-01'), (date '2020-06-01') )
, base_dates( fsun, fmon) as
( select utl_dates_first_dow_of_month('Sun',dt)
, utl_dates_first_dow_of_month('Mon',dt)
from parms
)
select '1st & 3rd Sunday and 1st & 3rd Monday'
, fsun "1st Sunday"
, (fsun+interval '14 days')::date "3rd Sunday"
, fmon "1st Monday"
, (fmon+interval '14 days')::date "3rd Monday"
from base_dates;
For the 1st and 3rd Sunday of the month and the Monday following:
with parms (dt) as (values ( date '2020-04-01'), (date '2020-06-01') )
, base_dates( fsun, fmon) as
( select utl_dates_first_dow_of_month('Sun',dt)
, (utl_dates_first_dow_of_month('Sun',dt)+interval '1 day')::date
from parms
)
select '1st & 3rd Sunday and Monday Following '
, fsun "1st Sunday"
, fmon "1st Monday"
, (fsun+interval '14 days')::date "3rd Sunday"
, (fmon+interval '14 days')::date "3rd Monday"
from base_dates;
select * from
(
select dow, i, row_number() over(partition by dow order by i) as rnk from
(
select
extract(dow from i::date) as dow,
i::date
from generate_series('2022-10-01'::date,'2022-10-31'::date,interval '1 Day') i
) tmp where dow = 1
)tmp_out where rnk = 3;
I need to generate a report on 28th of every month .
So for that I need to run an autosys job.
In that I have a query with the condition
validation_date >= (number of days since last run)
Could you please help me on this .How can I achieve this condition in DB2 ?
This is a monthly job.So I don't want to hard code my previous run date in the query .At the same time I need to get a condition which satisfies for all the months .
Note :
If the query is running on feb 28th ,then feb 28th is not included. I need to get data from january 28th(included) till feb 27th(included)
similarly for march 28th run ,I need to get data from feb 28th(included) till march 27th(included)...Thanks in advance.Please help
Consider putting your report generation in a procedure, and parameterizing the start and end dates. In other words, have something like this:
create procedure monthly_report(
start_date date,
end_date date
)
language sql
begin
... report queries here ...
end
Now you potentially have something much more flexible (depending on the report requirements). If, in the future, you want to run a report on a different day, or for a different length of time, you will be able to do that.
Once you design it this way, it also may be easier to set the dates in your job scheduling script, rather than in SQL. If you did it in SQL, you could do something like this:
call monthly_report(
(select
year(current timestamp - 2 months) ||'-'||
month(current timestamp - 2 months) ||'-'||
'28' from sysibm.sysdummy1
),
(select
year(current timestamp - 1 month) ||'-'||
month(current timestamp - 1 month) ||'-'||
'27' from sysibm.sysdummy1
)
)
You may need to tweak it to handle some edge cases (I'm not exactly sure if you care what happens if it runs on the 29th of the month, and if so, how to handle it). But you get the basic approach.
You can use DAY() function that extracts day of month from date and you can use it for triggering job. for example where day(param)=28.
other two parameters can be calculated with date calculation , here is example for trigger , date_to value and date_from value
select day(timestamp_format(20170228,'yyyyMMdd') ),timestamp_format(20170228,'yyyyMMdd')- 1 DAY,timestamp_format(20170228,'yyyyMMdd') -1 month from sysibm.sysdummy1;
if your parameter/column is date/timestamp you can remove timestamp_format(20170228,'yyyyMMdd') function and just put your column/parameter
I've been working on this problem for a while now. Basically I have a simple set of data with UserId, and TimeStamp. I want to know how many distinct UserId's appear each week, the catch is my week is measured in Sunday-Saturday, NOT Monday - Sunday, which is what Weekofyear() uses.
Right now I'm hardcoding each week and running the query:
SELECT
count(distinct UserId)
FROM data.table
where from_unixtime((CAST(timestamp as BIGINT)))
between TO_DATE("2016-06-05") AND TO_DATE("2016-06-12")
I'm trying to find a way to shift the timestamp back a day to trick weekofyear into thinking my Sunday is actually a Monday, but have not been successful. My latest futile attempt looked like:
SELECT
count(distinct UserId), weekofyear(date_sub(from_unixtime(CAST(timestamp as BIGINT)),1))
FROM table.data
where from_unixtime((CAST(timestamp as BIGINT)))
between TO_DATE("2016-06-01") AND TO_DATE("2016-06-30")
group by weekofyear(date_sub(from_unixtime(CAST(timestamp as BIGINT)),1))
This results in the same numbers as if I didn't subtract a day. I not sure why this isn't working. I feel like there should be a way to manage this. Right now if I wanted to pull all the data by week WHERE X is true, I'd have to manually do each week, that won't be sustainable. Any suggestions on how to work smarter?
Thank you.
Simple Solution
You can simply create your own formula instead of going with pre-defined function for "week of the year"
Advantage: you will be able to take any set of 7 days for a week.
In your case since you want the week should start from Sunday-Saturday we will just need the first date of sunday in a year
eg- In 2016, First Sunday is on '2016-01-03' which is 3rd of Jan'16
--assumption considering the timestamp column in the format 'yyyy-mm-dd'
SELECT
count(distinct UserId), lower(datediff(timestamp,'2016-01-03') / 7) + 1 as week_of_the_year
FROM table.data
where timestamp>='2016-01-03'
group by lower(datediff(timestamp,'2016-01-03') / 7) + 1;