To INSERT values from CTE result - sqlite

I have 'SchoolYearStartEnd' table
CREATE TABLE SchoolYearStartEnd (
id INT PRIMARY KEY UNIQUE,
StartDate DATE,
EndDate DATE
);
and the second 'SchoolYearsTeachingDays' table
CREATE TABLE SchoolYearsTeachingDays (
aDate DATE PRIMARY KEY UNIQUE
);
which I want to fill out with dates from a CTE like this:
WITH RECURSIVE dates(x) AS (
SELECT (SELECT StartDate FROM SchoolYearStartEnd)
UNION ALL
SELECT DATE(x, '+1 DAYS') FROM dates WHERE x < (SELECT EndDate FROM SchoolYearStartEnd)
)
SELECT * FROM dates WHERE CAST(STRFTIME('%w',x) AS INTEGER) > 0
;
I tried with this code here:
INSERT INTO SchoolYearsTeachingDays (aDate) VALUES (
WITH RECURSIVE dates(x) AS (
SELECT (SELECT StartDate FROM SchoolYearStartEnd)
UNION ALL
SELECT DATE(x, '+1 DAYS') FROM dates WHERE x < (SELECT EndDate FROM SchoolYearStartEnd)
)
SELECT * FROM dates WHERE CAST(STRFTIME('%w',x) AS INTEGER) > 0 -- To exclude Sundays.
;
);
but without success. I get these errors:
Error: near "RECURSIVE": syntax error
Error: near ")": syntax error
So what am I missing here?
Best, Pal

When you are inserting from a SELECT query, you must not use VALUES:
INSERT INTO SchoolYearsTeachingDays (aDate)
WITH RECURSIVE dates(x) AS (...)
SELECT * FROM dates ...;

Related

Teradata macro with volatile table and CTE to insert data into a table

I need to create a teradata macro to extract information into a volatile table first, then do CTE to extract data from this volatile table and insert into a teradata table, tried different ways all fail, appreciate help!
CREATE MACRO database.macro_insertion_tablename AS (
CREATE VOLATILE TABLE vt AS
(
SELECT
id, bu,
CONCAT(TO_CHAR(comment_date, 'yyyy-mm-dd HH24:MI:SS'), ' ', action) AS full_action,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY date DESC) AS row_num,
COUNT(*) OVER (PARTITION BY id) as cnt
FROM database.table1
) WITH DATA UNIQUE PRIMARY INDEX(id, row_num) ON COMMIT PRESERVE ROWS;
WITH RECURSIVE cte (id, bu, act, rn) AS
(
SELECT
id, bu
,CAST(full_action AS VARCHAR(5000)) AS full_action
,row_num
FROM vt
WHERE row_num = cnt
UNION ALL
SELECT
vt.id, vt.bu
,cte.act || ' / ' || vt.full_action
,vt.row_num
FROM vt
JOIN cte On vt.id = cte.id AND vt.row_num = cte.rn - 1
)
INSERT INTO database.table (id, bu, full_action)
SELECT id, bu, act
FROM cte
WHERE rn = 1;
DROP TABLE vt;
);
DDL must be the only statement in a Teradata Macro.
As workaround you could switch to a Global Temporary Table which is defined once and then you simply Insert/Select into it instead of CREATE VOLATILE TABLE.
But in your case there's no need for a temp table plus inefficient recursive processing to get a "group concat":
SELECT id, max(bu) -- maybe min(bu)?
XmlAgg(Concat(To_Char(comment_date, 'yyyy-mm-dd HH24:MI:SS'), ' ', action)
ORDER BY comment_date) (VARCHAR(5000)) AS full_action
FROM database.table1
GROUP BY 1
will give you a similar result.
To follow up on my comments, you should be able to define multiple CTEs in the same statement. It may be tricky getting the RECURSIVE CTE to work, but it sounds like it's possible. Maybe something like this:
CREATE MACRO database.macro_insertion_tablename AS (
WITH vt (id, bu, full_action, row_num, cnt) AS
(
SELECT
id, bu,
CONCAT(TO_CHAR(comment_date, 'yyyy-mm-dd HH24:MI:SS'), ' ', action) AS full_action,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY date DESC) AS row_num,
COUNT(*) OVER (PARTITION BY id) as cnt
FROM database.table1
),
RECURSIVE cte (id, bu, act, rn) AS
(
SELECT
id, bu
,CAST(full_action AS VARCHAR(5000)) AS full_action
,row_num
FROM vt
WHERE row_num = cnt
UNION ALL
SELECT
vt.id, vt.bu
,cte.act || ' / ' || vt.full_action
,vt.row_num
FROM vt
JOIN cte On vt.id = cte.id AND vt.row_num = cte.rn - 1
)
INSERT INTO database.table (id, bu, full_action)
SELECT id, bu, act
FROM cte
WHERE rn = 1;
);
I don't have a Teradata system to test with, so not 100% it will work as-is, but give it a try. You may need to change RECURSIVE to WITH RECURSIVE and also the ordering of the CTE queries (i.e. put the RECURSIVE one first). Take a look at these two links:
Teradata Forum - Multiple With Clause
teradata Forum - Common Table Expressions

Oracle to_date return incorrect result

I have a table 4 columns - Code, Status, EffectiveDate (EFF_DT), EndDate (END_DT). All the columns are Varchar2 type. EFF_DT and END_DT has ISO format date (YYYY-MM-DD) with NULL values for few rows. Need to get the rows which has END_DT greater than today's date.
While executing the below query, it returns all the Not NULL rows for END_DT. Do not compare the END_DT at all.
select code, status, EFF_DT, END_DT
from (
select CODE, EFF_DT, Status,to_date("END_DT" ,'YYYY-MM-DD' ) as END_DT
from xxx.ZZZ
) TAB
where to_date(TAB.END_DT ,'DD-MM-YY' ) > to_date(CAST(CURRENT_TIMESTAMP as Date), 'DD-MM-YY')
ORDER BY 1 ASC
But the below query compares the END_DT and returns the result properly -
SELECT "TAB"."CODE" , "TAB"."STATUS" AS "STATUS" , "TAB"."EFF_DT" , "TAB"."END_DT"
FROM xxx.ZZZ "TAB"
WHERE ( (to_date("TAB"."END_DT",'YYYY-MM-DD') > to_date(CAST(CURRENT_TIMESTAMP as Date), 'YY-MM-DD')) )
ORDER BY 1 ASC
What is going wrong with the 1st query?
I see difference in return value of END_DT.
For the 1st query, the data is coming like -
while as for the 2nd query, the data is coming like

Return 0 if the date for a certain day does not have values

I'm doing a query to return the number of count records for a certain date.
The problem is when I use the GroupBy by a certain day, If the date have no records then the date for that day will not be shown in the output.
How can I achieve that?
I'm doing something like:
SELECT COUNT(History.Id)
FROM History
INNER JOIN User ON User.Id = History.UserId
WHERE (#StartDate = #NullDate OR History.CreatedOnDate >= #StartDate)
AND (#EndDate = #NullDate OR History.CreatedOnDate <= #EndDate)
GROUP BY History.CreatedOnDat
Example
01-08, 3 records
02-08, 2 records
04-08, 5 records
I need to have 03-08 with 0 records.
Create a temp table with one day per row:
Declare #StartDate datetime = '2016-08-01'
Declare #EndDate datetime = '2016-08-31'
declare #temp table
(
oneday datetime
);
WHILE #StartDate <= #EndDate
begin
INSERT INTO #temp VALUES (#StartDate);
SET #StartDate = Dateadd(Day,1, #StartDate);
end
select * from #temp
Then, simply join your query with this temp table.

Conversion failed when converting character string to smalldatetime data type

SELECT B.Value
FROM table1 A WITH (NOLOCK)
INNER JOIN table2 B WITH (NOLOCK) ON A.id = B.id
WHERE
A.Name = 'COMPLETED_AT'
AND CONVERT(smalldatetime, A.Value) < GETDATE() - 30
AND B.Name = 'RESULT'
Getting error message
Conversion failed when converting character string to smalldatetime data type
when executing the above query
Example table structure
ID Name Value
1 Result R12344
1 Completed_At 2015-03-20T06:06:46
2 Result R23445
2 Completed_At 2014-03-20T06:06:46
Column value is of nvarchar(400) datatype
The query result should display the values of result name type which have been made an entry of more than 30 days.
Looking forward in hearing from you.
Avoid Null In Datetime Coloumn field & fix this error (Conversion failed when converting character string to smalldatetime data type.):
First, I give this type get this error:
select * from Tabel1 where ISNULL(Datecoloumn1,**'0'**)!='1900-01-01 00:00:00'
The single quotation Zero is the Problem
I fix like this method :
select * from Tabel1 where ISNULL(Datecoloumn1,**0**) != '1900-01-01 00:00:00'
It works just fine, just changed Table2 to Table1, because you said is a self join.
CREATE TABLE Table1
([ID] int, [Name] varchar(12), [Value] varchar(19))
;
INSERT INTO Table1
([ID], [Name], [Value])
VALUES
(1, 'Result', 'R12344'),
(1, 'Completed_At', '2015-03-20T06:06:46'),
(2, 'Result', 'R23445'),
(2, 'Completed_At', '2014-03-20T06:06:46')
;
SELECT B.Value
FROM table1 A WITH (NOLOCK)
INNER JOIN table1 B WITH (NOLOCK) ON A.id = B.id
WHERE
A.Name = 'COMPLETED_AT'
AND CONVERT(smalldatetime, A.Value) < GETDATE() - 30
AND B.Name = 'RESULT'
Result
Value
R23445

Select Record with Repeated Status using Sql Query

i have one Schedule Table like
i want to look like select query data is:
1 and 11 is Duplicate trainer and Duplicate day,time
10 and 12 is Duplicate trainer, Duplicate vanueid and Duplicate date,time
so last two column are display is not Duplicate than available and is Duplicate than display notavailable
Here is the solution that is coming to my mind.There may some syntax issue but i given the logic which may help you.
DECLARE #duplicate TABLE (
trainerId INT,
dt varchar(50)
)
INSERT INTO #duplicate SELECT TrainerId , [Date] from tbl GROUP BY TrainerId , Date HAVING (COUNT(*) > 1)
SELECT * FROM #duplicate
DECLARE #tempTable TABLE (
trainerId INT,
dt varchar(50),
status int
)
INSERT INTO #tempTable
SELECT trainerId , [Date] , STATUS = (SELECT COUNT(*) FROM #duplicate where trainerId = tbl.TrainerId and dt = tbl.Date) FROM tbl
![enter image description here][2]SELECT * , CASE [status] WHEN 0 THEN 'Available' ELSE 'Not Available' END FROM #tempTable

Resources