Teradata : using case statement in Where clause - case

My question is about using case statement in where clause to check for date and assign values to columns. My sample code include.
select * from table
where
column 1 > 10 and
case when column 2 = 1
then
column 3<= 10 and column 4 between (1st day of prev month) and (prev month end) or column 5 = '8888-01-01'
else
column 4 between (1st day of this month) and (yesterday)
end ;
when I am running this code. I am getting 3706 syntax error:expected something in between field and '='.
How to fix this ?

A CASE statement will always return a value or NULL (if none of the conditions matches), so you can use it in your WHERE clause. There are a couple ways to format your CASE statement:
Format 1
CASE
WHEN <condition> THEN <some_expression>
WHEN <another_condition> THEN <another_expression>
ELSE <final_expression>
END
-- Example
CASE
WHEN col1 = 10 THEN 'Y'
WHEN col1 = 20 THEN 'N'
ELSE 'N/A'
END
Format 2
CASE <expression>
WHEN <value> THEN <expression>
WHEN <another_value> THEN <another_expression>
ELSE <final_expression>
END
-- Example
CASE col1
WHEN 10 THEN 'Y'
WHEN 20 THEN 'N'
ELSE 'NA'
END
I'm not sure what you're trying to do with your sample code, but it looks more like pseudo-code and will not work as-is. Your CASE statement is not formatted properly and your column references like column 1 will not work that way. If your column is actually named column 1, then you need to put double-quotes around it:
select * from table where "column 1" > 10
Can you please describe a little more clearly what exactly you are trying to do?

A CASE expression can't be used to create some kind of dynamic conditions. Write it as a bunch of AND/OR conditons:
select * from table
where
column 1 > 10 and
(
( column 2 = 1 and
(column 3<= 10 and column 4 between (1st day of prev month) and (prev month end) or column 5 = '8888-01-01')
)
or
column 4 between (1st day of this month) and (yesterday)
);
Double check the logic, the precedence of logical operators is
parenthesis
NOT
AND
OR

Related

Count in xquery

I'm trying to solve this question but this code give me the result without counting it. What i mean it's that i need it to be a 13 but the result its divided by rows with a value of 1.
1
1
1
1
1
1
1
1
1
1
1
1
1
This is the question and this is what i have done.
List the number of countries that have a border (element ) in a country that has a Buddhist religion (element , value "Buddhist"). The correct query has to return the value 13.
for $var in /mondial/country
let $religion:=/mondial/country[religions="Buddhist"]/data(#id)
where $var /border/#country=$religion
return data (count($var/name)
This should get you there. I changed variable names to make things a bit more readable:
let $country := mondial/country
let $buddhist := $country[religions[./text()="Buddhist"]]/#id
return count($country[.//border[#country=$buddhist]])
Output:
13
Rather than returning the count for each item as you iterate, return each selected item and assign it to a variable, then you can get a count of the items of the sequence assigned to that variable:
let $names :=
for $var in /mondial/country
let $religion:= /mondial/country[religions="Buddhist"]/data(#id)
where $var/border/#country=$religion
return $var/name
return count($names)
You could also do this in a single XPath statement:
count(/mondial/country[border/#country=/mondial/country[religions="Buddhist"]/data(#id)])

I have Year & Month but need to incorpate month number also

This is my value in the table : FY20 JAN
And i am looking for 'FY20 (M01) JAN'. How can convert like this in Oracle 11g SQL query ?
First you convert your string to a value of DATE type. Anything enclosed in double quotes is somewhat hard coded and TO_DATE function ignores them as long as they match the characters in the input in their specific locations. Here FY are in location (index) 1 and 2.
alter session set nls_date_format = 'yyyy-mm-dd';
select to_date('FY20 JAN', '"FY"yy MON') d from dual;
D
----------
2020-01-01
Then, you apply another function TO_CHAR to the date value we got above to get the desired output.
select to_char(
to_date('FY20 JAN', '"FY"YY MON')
, '"FY"yy "(M"mm")" MON'
) c from dual;
C
-----------------------
FY20 (M01) JAN

SQLITE Join on Date = Date + x

I am using the following insert query to create a comparison between two tables using the dates to join on.
INSERT INTO Comp_Table (Date, CKROne, CKRTwo, ChangeOne, ChangeTwo, State)
SELECT BaseTbl.Date, BaseTbl.CKR, CompTbl.CKR, BaseTbl.Change, CompTbl.Change,
CASE
WHEN BaseTbl.Change > 0 AND CompTbl.Change > 0 THEN 'positive'
WHEN BaseTbl.Change < 0 AND CompTbl.Change < 0 THEN 'positive'
ELSE 'inversely'
END AS 'Correlation'
FROM BaseTbl
JOIN CompTbl ON BaseTbl.Date = CompTbl.Date;
This works well. However, I would like to be able to join the tables with a lag. As in, the user can define if they want to do exact match on dates or if they want to use a date of one's occurrence plus a number and return the value from the latter date for comparison to the number to the former date. Pseudo code example:
User sets variable = 0 then
Join ComTbl On BaseTbl.Date = CompTbl.Date + 0;
User sets variable = 7 then
Join CompTbl On BaseTbl.Date = CompTbl.Date + 7;
(joins 2012-01-01 from BaseTbl to 2012-01-08 from CompTbl)
I tried to add days like you would in a Where clause ('+7 day'), but this didn't work. I also tried to using a Where clause with BaseTbl.Date = CompTbl.Date '+ 7 day' but that returned a 0 value also. How can this be accomplished in SQLite?
I think you can use the DATE() function to build the WHERE clause you want:
INSERT INTO ...
SELECT ...
FROM BaseTbl
INNER JOIN ComTbl
ON BaseTbl.Date = DATE(CompTbl.Date, '7 days')

How to create a column for even and odd records dynamically?

I have a query in Teradata. I want to add an additional column that would be a VARCHAR.
It should say whether the selected record is even or odd
select id, name, CASE newColumn WHEN --- ???
from my table
Like this
id name newColumn
1 asdf odd
2 ts df even
32 htssdf odd
4 asdfsd even
23 gftht odd
How can I do this
Based on your example, I can't tell how you are sorting the results. You would need to define a sort order. Let's assume you would do it based on the id number.
SELECT id, name,
ROW_NUMBER() OVER(ORDER BY id) row_id,
CASE WHEN ROW_NUMBER() OVER(ORDER BY id) MOD 2 = 0 THEN 'Even' ELSE 'Odd' END newColumn
FROM my table
The row_id is incrementally assigned based on the id field being sorted ascending. You then use the MOD function to determine if there's a remainder after dividing the number by a value (in this case 2). Result would look like the following:
id name row_id newColumn
1 asdf 1 Odd
2 ts df 2 Even
4 asdfsd 3 Odd
23 gftht 4 Even
32 htssdf 5 Odd

sqlite returns 0 rows

SELECT skill_name, character_name, cb_id, cb_id2 FROM characterbasics, characterskills WHERE characterbasics.character_name = 'Joe' & characterbasics.cb_id = characterskills.cb_id2
This, for some reason, returns 0 rows
The character name is in there (as well as 2 other dummy names).. and both cbid and cbid2 are the same.
When i try the query without the & cbid=cbid2 i get the name with the other data.. now when i check for JUST cbid=cbid2 i get 3 different dummy characters i created...
im trying to pull all "skills" associated with one character by matching the id of the character name in table 1 with the character id in table 2
Where have I erred?
cn = character name
cn cbid cbid2
Joe 2 2
This is what it SHOULD look like..
You cant use & as logical AND operator (& is binary operator), so sql should look like :
SELECT skill_name, character_name, cb_id, cb_id2
FROM characterbasics, characterskills
WHERE characterbasics.character_name = 'Joe' AND characterbasics.cb_id = characterskills.cb_id2

Resources