I'd like to take this query (which works for me):
SELECT(DATE_ADD(DATE(CURRENT_TIMESTAMP()), INTERVAL 1* n MONTH)) as date
FROM UNNEST(GENERATE_ARRAY(0,12,1)) n
And replace the CURRENT_TIMESTAMP() with a start_date timestamp field from an existing table.
In other words, I'd like to create a list of "active months" for a contract that begins on start_date.
I'm getting stuck on how to incorporate another FROM clause!
This should work:
SELECT(DATE_ADD(DATE(start_date), INTERVAL 1* n MONTH)) as date
FROM ExistingTable, UNNEST(GENERATE_ARRAY(0,12,1)) n
If you have exactly one row in the existing table representing the start date, you can use a subselect:
SELECT(DATE_ADD(DATE((SELECT start_date FROM ExistingTable)), INTERVAL 1* n MONTH)) as date
FROM UNNEST(GENERATE_ARRAY(0,12,1)) n
Related
I'm new to Qlik loops
I need to create dates until 2024.
I have the following data:
The Date column is a date that I retrieve from my database
The Periodicity column (these are months). This column I retrieve directly from my database.
Column Date 1 and Date 2 are columns I need to calculate in Qlik.
I want to loop to calculate these two columns, and the calculations are as follows:
Example for PN 10101, Date: 01/02/2022, Periodicity = 12
Date_1 = AddMonths(Date,periodicity) ----> 01/02/2023
Date_2 = AddMonths(Date_1,periodicity) -----> 01/02/2024
I only want to have 2 dates by PN (One date in 2023 and another in 2024). I don't want to generate multiple dates until 2024.
thank you in advance for your help
No need to loop in this case.
DataBaseData:
Load
PN,
Date,
// Define Date_1
AddMonths(Date,Periodicity) as Date_1,
// Wrap AddMonths into another AddMonths to get the second field
AddMonths(Date,AddMonths(Date,Periodicity), Periodicity) as Date_2,
Periodicity
From
[some-database]
;
The other approach is to use Preceding LOAD feature.
TLDR; Preceding load allows you to have nested loads that results in one table. Each preceding load takes the inner load result as an input.
DataBaseData:
// In the second step use the already available Date_1
// field and calculate Date_2
// * - will load all fields from the previous table
Load
*,
AddMonths(Date_1,Periodicity) as Date_2,
;
// In the first step calculate Date_1 fiels
Load
PN,
Date,
AddMonths(Date,Periodicity) as Date_1,
Periodicity
From
[some-database]
;
P.S. The order of loading/executing, in the case of preceding load, is from bottom to top
Let’s say I have a table that has one column as timestamp ntz. I want to perform a select that calculates the number of seconds difference between that moment in the table vs the start of that date. For pure timestamp type I can just use the timediff function:
select timediff(second,
‘2022-01-01 00:00:05’::timestamp_ntz,
‘2022-01-01 00:00:00’::timestamp_ntz
)
Which returns 5.
How can I do it with a value in a table, for example:
select timediff(second, my_date, my_date_startofdate)
Where my_date_startofdate will be converted to that day but at time 00:00:00.
Use date_trunc. This function takes a timestamp or date and truncates it to whatever element you want. So, if you take your timestamp column and trunc it day, it removes the time elements and gives you the beginning of the day.
select timediff(second, date_trunc('day',my_date), my_date)
https://docs.snowflake.com/en/sql-reference/functions/date_trunc.html
I would like to select from a partitioned table where the date is the highest date strictly below a given date d.
I can do the following:
d:2019.10.02;
{select from x where date = max date} select from t where date < d
where t is my partitioned table.
The issue with the above query is that it is very slow as it has to first load all the dates strictly older than d, and then taking the max date out of it.
To select all the dates that are earlier than your specified date you can use the select statement below:
select from t where date=max date where date<d
Where t is your partitioned table and d is your specified date.
If you just want to select from the max date in a date partitioned hdb
Lets assume that the max populated date partition less than 2019.08.20 is 2019.08.07
q)d:2019.08.20
q)select from t where date=max date where date<d
This is because the partition type is available as a variable once you load into a DB, (i.e,. date, month, int etc). This will be the .Q.pf variable.
select from table where date=(last .Q.pv where .Q.pv < d)
kdb+ stores a variable in memory which contains all the dates within your db.
select from telemetry where date=desc[date]1
Above where clause will sort this by largest ->smallest
Selecting index 1 will filter the max date out of your query (without first querying the entire dataset).
I need to select from a table that has two fields , a start date and an end date , selecting the row that the current date is. Look at the image ...how do i select the row that encompasses the date range 91/201 - 9/15/2018 ? Somehow this was flagged as a duplicate. I am NOT attempting to find overlap. I am attempting to find the row that represents a given date. Say , one table has a field that has the value 9/5/2018 ....how do I select the row that has a start date of 9/1/2018 and end date of 9/15/2018
I'm working on a system to store appointments and recurring appointments. My schema looks like this
Appointment
-----------
ID
Start
End
Title
RecurringType
RecurringEnd
RecurringTypes
---------------
Id
Name
I've keeped the Recurring Types simple and only support
Week Days,
Weekly,
4 Weekly,
52 Weekly
If RecurringType is null then that appointment does not recur, RecurringEnd is also nullable and if its null but RecurringType is a value then it will recur indefinatly. I'm trying to write a stored procedure to return all appointments and their dates for a given date range.
I've got the stored procedure working for non recurring meetings but am struggling to work out the best way to return the recurrences this is what I have so far
ALTER PROCEDURE GetAppointments
(
#StartDate DATETIME,
#EndDate DATETIME
)
AS
SELECT
appointment.id,
appointment.title,
appointment.recurringType,
appointment.recurringEnd,
appointment.start,
appointment.[end]
FROM
mrm_booking
WHERE
(
Start >= #StartDate AND
[End] <= #EndDate
)
I now need to add in the where clauses to also pick up the recurrences and alter what is returned in the select to return the Start and End Dates for normal meetings and the calculated start/end dates for the recurrences.
Any pointers on the best way to handle this would be great. I'm using SQL Server 2005
you need to store the recurring dates as each individual row in the schedule. that is, you need to expand the recurring dates on the initial save. Without doing this it is impossible to (or extremely difficult) to expand them on the fly when you need to see them, check for conflicts, etc. this will make all appointments work the same, since they will all actually have a row in the table to load, etc. I would suggest that when a user specifies their recurring date, you make them pick an actual number of recurring occurrences. When you go to save that recurring appointment, expand them all out as individual rows in the table. You could use a FK to a parent appointment row and link them like a linked list:
Appointment
-----------
ID
Start
End
Title
RecurringParentID FK to ID
sample data:
ID .... RecurringParentID
1 .... null
2 .... 1
3 .... 2
4 .... 3
5 .... 4
if in the middle of the recurring appointments schedule run, say ID=3, they decide to cancel them, you can follow the chain and delete the remaining ID=3,4,5.
as for expanding the dates, you could use a CTE, numbers table, while loop, etc. if you need help doing that, just ask. the key is to save them as regular rows in the table so you don't need to expand them on the fly every time you need to display or evaluate them.
I ended up doing this by creating a temp table of everyday between the start and end date along with their respective day of the week. I limited the recurrence intervals to weekdays and a set amount of weeks and added where clauses like this
--Check Week Days Reoccurrence
(
mrm_booking.repeat_type_id = 1 AND
#ValidWeeklyDayOfWeeks.dow IN (1,2,3,4,5)
) OR
--Check Weekly Reoccurrence
(
mrm_booking.repeat_type_id = 2 AND
DATEPART(WEEKDAY, mrm_booking.start_date) = #ValidWeeklyDayOfWeeks.dow
) OR
--Check 4 Weekly Reoccurences
(
mrm_booking.repeat_type_id = 3 AND
DATEDIFF(d,#ValidWeeklyDayOfWeeks.[Date],mrm_booking.start_date) % (7*4) = 0
) OR
--Check 52 Weekly Reoccurences
(
mrm_booking.repeat_type_id = 4 AND
DATEDIFF(d,#ValidWeeklyDayOfWeeks.[Date],mrm_booking.start_date) % (7*52) = 0
)
In case your interested I built up a table of the days between the start and end date using this
INSERT INTO #ValidWeeklyDayOfWeeks
--Get Valid Reoccurence Dates For Week Day Reoccurences
SELECT
DATEADD(d, offset - 1, #StartDate) AS [Date],
DATEPART(WEEKDAY,DATEADD(d, offset - 1, #StartDate)) AS Dow
FROM
(
SELECT ROW_NUMBER() OVER(ORDER BY s1.id) AS offset
FROM syscolumns s1, syscolumns s2
) a WHERE offset <= DATEDIFF(d, #StartDate, DATEADD(d,1,#EndDate))
Its not very elegant and probably very specific to my needs but it does the job I needed it to do.