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
Related
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'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
Scenario: a user will copy and paste data (multiple rows) from an Excel sheet onto my webpage and press submit. When this occurs, the data will be saved into a SQL Server table. The current date will also be saved next to each row.
Now, in another gridview, I would like to view only these multiple rows that have been pasted /saved to DB that certain day.
So I was thinking about using TOP / MAX(date) but Top returns specified rows only, and MAX only 1 row.
Anyone out there that has done this before or can help get a working query?
Use TOP WITH TIES in order to get all last entries:
SELECT TOP(1) WITH TIES
...
ORDER BY submit_date DESC;
Is "that certain day" based on a specific day or a 24 hour interval?
You can make the gridview query the data where the date field is higher than or equal to dateadd(dd, -1, getdate())
Or if you mean the current day as in the current date, where the date is equal to the date of getdate.
I am trying to import an xls spreadsheet into a table, and one of the columns needs to be derived from a different column in the same table. I would like to do this during the import phase rather then creating a SQL Task to do it after the import. I am horrible when it comes to creating expressions in SSIS, so this is probably an easy task - but I just can't get it right.
DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,columndata)+1,0))
That is the expression that I am trying to use.
You want the following:
DATEADD("S",-1,DATEADD("M",DATEDIFF("M", (DT_DATE) 0,DATEADD("D",[dataDate],(DT_DATE)-2))+1,(DT_DATE)0) )
1) You need to use " to surround your dateparts.
2) You need to cast your 0 date to an explicit date type.
This expression takes the column dateserial number [dataDate] adds that number of days to the date -2
DATEADD("D",[dataDate],(DT_DATE)-2)
(apparently sql day 0 and excel day 0 are different by 2 days on my versions (sql2008r2 and excel 2007)) and finds the number of months from date 0 to that date,
DATEDIFF("M", (DT_DATE) 0,DATEADD("D",[dataDate],(DT_DATE)-2))
then adds 1 to that number of months and adds it back to date 0
DATEADD("M",DATEDIFF("M", (DT_DATE) 0,DATEADD("D",[dataDate],(DT_DATE)-2))+1,(DT_DATE)0)
(to get the beginning of the next month following the column date value), Then it subtracts 1 second from the date to get the last second of the month of the column date value in the datetime format.
DATEADD("S",-1,DATEADD("M",DATEDIFF("M", (DT_DATE) 0,DATEADD("D",[dataDate],(DT_DATE)-2))+1,(DT_DATE)0) )
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.