I am trying to run the following Teradata (V 14.10.3.09) DB query using Teradata Studio:
WITH params AS
(
SELECT
TO_TIMESTAMP(TO_CHAR(CURRENT_TIMESTAMP, 'yyyy-mm-dd hh24'),'yyyy-mm-dd hh24') AS w0s -- truncate to the current hour
,CURRENT_TIMESTAMP AS w0e
,CURRENT_DATE -8 AS w1s
,CURRENT_DATE -1 AS w1e
)
SELECT ST_NM
,SUM(CASE WHEN CRT_DTTM>=w0s AND CRT_DTTM<w0e THEN 1 ELSE 0 END) AS Call_Volume_This_hr
,SUM(CASE WHEN CRT_DTTM>=w1s AND CRT_DTTM<w1e THEN 1 ELSE 0 END)/7.0 AS Avg_Call_Volume_Past_Week1
,CASE WHEN Call_Volume_This_hr < Avg_Call_Volume_Past_Week1 THEN 0
ELSE Call_Volume_This_hr -Avg_Call_Volume_Past_Week1
END AS VARIANCE
,(100 * VARIANCE) / Avg_Call_Volume_Past_Week1 AS Percentage_Variance
FROM XDW_V.INB_CALL_NRT_RPT
WHERE CRT_DTTM>=w1s
AND EXTRACT(HOUR FROM CRT_DTTM)=EXTRACT( HOUR FROM CURRENT_TIMESTAMP)
AND ST_NM IS NOT NULL
GROUP BY ST_NM;
But getting the syntax error:
SQL Editor: Encountered "WITH params AS. Was expecting one of: "alter" ... "call" ... "create" ... "drop" ... "dump" ... "logging" ... "replace" ...
"replication" ... "restart" ... "restore" ... ";" ... "dynamic" ... "explain" ... "lock" ... "locking" ... "with" ... "with" "recursive" ... "with" "(" ... "(" ... "validtime" ...
"current" ... "transactiontime" ... "nontemporal" ... "as" ... "select" ... "sel" ... "retrieve" ... "ret" ... "cd" ... "modify" ... "give" ... "rename" ... "cm" ... "delete" ...
"del" ... "release" ... "revalidate" ... "rollback" ... "rollforward" ... "checkpoint" ... "insert" ... "ins" ... "update" ... "upd" ... "merge" ... "set" ... "commit" ...
"abort" ... "begin" ... "bt" ... "end" ... "et" ... "ct" ... "grant" ... "cv" ... "revoke" ... "help" ... "show" ... "mload" ... "execute" ... "exec" ... "comment" ... "collect" ...
"database" ... "echo" ... "ss" ... "diagnostic" ... "initiate" ...
I tried a few random things like removing "WITH"and replacing "AS" with "IS" which I know is not very good effort. Can someone suggest me what should be the correct syntax for this type of query as I think I am missing something related to syntax.
UPDATE: What I am trying to do is (forgot to add in original post)
If CURRENT_TIMESTAMP is say 2015-08-20 16:27:42.987 Then
fetch count(*) grouped by each state where Create_time is between
2015-08-20 16:00:00.000 to 2015-08-20 16:27:42.987.
Second
step is to find count() grouped by each state for past 7 days
(Aug/13 to Aug/19) during the same 1 hour window 16:00:00.000 to
17:00:00.000 and take sum of count() for past 7 days, and average
count(*) (divide sum by 7).
Third step is if the count()
for today (calculated in step1) is greater than average count()
then find the difference and display in a column (say Variance) and
also calculate percentage deviation by using (Variance/average
count(*)) * 100 and display in a column say percentage.
UPDATE: For no more spool space error I used advice to use inner join and the query started fetching result as expected. So the final query I am using now is:
WITH TEMP_TAB (w0s,w0e,w4s,w4e) AS
(
SELECT
TO_TIMESTAMP(TO_CHAR(CURRENT_TIMESTAMP, 'yyyy-mm-dd hh24'),'yyyy-mm-dd hh24') AS w0s
,CURRENT_TIMESTAMP AS w0e
,CURRENT_DATE -29 AS w4s
,CURRENT_DATE -1 AS w4e
)
SELECT ST_NM
,SUM(CASE WHEN CRT_DTTM>=w0s AND CRT_DTTM<w0e THEN 1 ELSE 0 END) AS Call_Volume_This_hr
,SUM(CASE WHEN CRT_DTTM>=w4s AND CRT_DTTM<w4e THEN 1 ELSE 0 END)/28.0 AS Avg_Call_Volume_Past_4Weeks
,CASE WHEN Call_Volume_This_hr < Avg_Call_Volume_Past_4Weeks THEN 0
ELSE Call_Volume_This_hr -Avg_Call_Volume_Past_4Weeks
END AS VARIANCE
,100 * VARIANCE / Avg_Call_Volume_Past_4Weeks AS Percentage_Variance
FROM XDW_V.INB_CALL_NRT_RPT INNER JOIN TEMP_TAB
ON 1=1
WHERE CRT_DTTM>=w4s
AND EXTRACT(HOUR FROM CRT_DTTM)=EXTRACT( HOUR FROM CURRENT_TIMESTAMP)
AND ST_NM IS NOT NULL
GROUP BY ST_NM;
Related
Update:
I want to insert data conditionally
Why this MariaDB query has errors:
if 2 > 1 then
select 'hi'
else
select 'bye'
end if
This is the error:
Error in query (1064): Syntax error near 'else select 'bye' end if' at line 3
if (exists (select * from teachers where name = 'Jennifer'))
then
-- do nothing
else
insert into teachers (name, age)
values ('Jennifer', 30)
end if;
I'm not sure that IF can be used like this outside of a stored procedure or function. You may use the IF() function or a CASE expression instead:
SELECT IF(2 > 1, 'hi', 'bye')
OR
SELECT CASE WHEN 2 > 1 THEN 'hi' ELSE 'bye' END
*where (citiStatus NOT IN ('Paid Off' ,'PAID-O'))
and (
revolver = 0
and (
(commitmentDate = '')
or (
(commitmentDate != '')
and (#currentDate < DATEADD(day, #noofDays, commitmentDate))
)
)
) // until here should verify with where condition . even if it is failed or not should execute next statement .
and (citiStatus NOT IN ('CANCELLED','Cancelled/Dead') or #currentMonth = MONTH(statusModifiedDate))-- this is will if above AND condition fails even if its true(but this should execute even to filter data).*
You need to have in mind two simple rules, the Associativity of Logical Operators is always from left to right, and the correct use of Parentheses having in consideration the logic of your problem for example:
select case when 1=1 and 1=2 or 3=3 then 1 else 0 end as result from dual;--result 1
First we evaluate 3=3 TRUE -> 1=2 FALSE -> evaluate OR OPERATOR (TRUE OR FALSE)-> TRUE
Second 1=1 TRUE -> evaluate AND OPERATOR -> TRUE AND TRUE -> TRUE
IF TRUE THEN 1
My advice is always to use Parentheses, in this way you will evaluate the whole expression and no token by token for example
select case when ((1=1 and 2=2) or 3=3) and 5=6 then 1 else 0 end as result from dual; --0
select case when (1=1 and 2=2) or (3=3 and 5=6) then 1 else 0 end as result from dual; --1
I got a problem with my request.
I want to compare 2 dates, and if the number of days is inferior to 2, i want to display nothing. But if it's over, I want to display the days.
I got my request but it failed when I try to compare the DATEDIFF to 2.
SQL> SELECT noLivraison, noCommande, noArticle, dateCommande, quantite, dateLivraison, quantiteLivree,
CASE dateCommande
WHEN DATEDIFF(day, dateLivraison, dateCommande) < 2 THEN null
ELSE DATEDIFF(day, dateLivraison, dateCommande)
END nombreJoursEcoules
FROM Commande
NATURAL JOIN LigneCommande
NATURAL JOIN Livraison
NATURAL JOIN DetailLivraison 2 3 4 5 6 7 8 9
10 /
WHEN DATEDIFF(day, dateLivraison, dateCommande) < 2 THEN null
*
ERROR at line 3:
ORA-00905: missing keyword
I don't know how to fix it, I put more parenthesis but it didn't works.
Ty for reading.
You can try the below code , may be it will solve your problem
select col1,col2,case when DATEDIFF(dd, dateLivraison, dateCommande)
>= 2 then 'days' else null end as 'datefield', DATEDIFF(dd, dateLivraison,
dateCommande) as 'days' from tablename
Thanks
I have:
PROCEDURE A
(
inId IN NUMBER,
RC1 OUT SYS_REFCURSOR
) IS
tMessage VARCHAR2(128);
BEGIN
OPEN RC1 FOR
SELECT * FROM
(
SELECT
a.company,
SUM(a.holding_balance) balance
FROM TableNameEntries A
WHERE
A.BATCH_ID = inId
GROUP BY a.company
)
ORDER BY balance DESC ;
EXCEPTION
WHEN OTHERS THEN
tMessage :='Exception ' || SQLCODE || ': ' || SQLERRM;
OPEN RC1 FOR
SELECT tMessage FROM DUAL;
END A;
For the balance column, I have values like -1, 0,1. Currently it's sorted like 1 0 -1, but I don't care about the zeros, so I want it to be like -1,1,0 or 1,-1,0
How do I do it in PL/SQL? I tried:
SELECT
a.company,
SUM(a.holding_balance) balance
FROM REC.CAG_GL_ENTRIES A
WHERE
A.BATCH_ID = 201311
order by case priority when 0 then 2 else 1 END priority
But it's saying PRIORITY is invalid identifier.
How can I get this to work?
Try:
ORDER BY CASE balance
WHEN 0 THEN null
ELSE balance
END
DESC NULLS LAST
there are two ways in your case (second is more common, first is more clear):
SELECT a.company,
SUM(a.holding_balance) balance
FROM REC.CAG_GL_ENTRIES A
WHERE A.BATCH_ID = 201311
order by abs(balance) desc;
SELECT a.company,
SUM(a.holding_balance) balance
FROM REC.CAG_GL_ENTRIES A
WHERE A.BATCH_ID = 201311
order by decode(balance,1,1,-1,1,2);
ORDER BY SIGN(ABS(balance)) DESC, balance
ABS() turns all the negatives to positives. SIGN() turns 0 to 0, >0 to 1 (and <0 to -1). Combined with DESC this puts all the zeros at the end and all the non-zeros above them in no particular order.
Then I sorted by the balance again to order the non-zeros.
You can also use
order by balance * balance desc
statement 1:
create table tmp as select code , round((max(close)-min(close))/min(close),2) as volatility,
case when (max(close)-min(close))/min(close) <0.1 then "grade1"
when (max(close)-min(close))/min(close) <0.2 then "grade2"
when (max(close)-min(close))/min(close) <0.3 then "grade3"
else "grade4" end as type
from quote where date between '20120801' and '20121101' and code<'07000'
group by code order by volatility ;
statement 2:
select tmp.code,profile.name, tmp.volatility from tmp,profile where tmp.code=profile.code;
the statement 1 and statement 2 can run ,when i combine the two into one --the statement 3,
it can't run ,what is the matter?
statement 3:
select quote.code ,profile.name, round((max(quote.close)-min(quote.close))/min(quote.close),2) as quote.volatility,
case when (max(quote.close)-min(quote.close))/min(quote.close) <0.1 then "grade1"
when (max(quote.close)-min(quote.close))/min(quote.close) <0.2 then "grade2"
when (max(quote.close)-min(quote.close))/min(quote.close) <0.3 then "grade3"
else "grade4" end as quote.type
from quote,profile where quote.date between '20120801' and '20121101' and quote.code<'07000' and quote.code=profile.code
group by quote.code order by quote.volatility ;
Just make your first statement a subquery:
select tmp.code, profile.name, tmp.volatility
from (select code,
round(...) as volatility,
case ... end as type
from quote
where date between '20120801' and '20121101'
and code<'07000'
group by code
order by volatility) as tmp,
profile
where tmp.code = profile.code;