so I have two column aliases that are using the same calculation:
,case when bi.PolicyFeeFactor = 0
then 0
else
CAST(ROUND(nb.AnnualPolicyFee * bi.PolicyFeeFactor,2)AS DECIMAL(6,2))
end
as UNIT_POLFEE_Y
,case when bi.PolicyFeeFactor = 0
then 0
else
CAST(ROUND(nb.AnnualPolicyFee * bi.PolicyFeeFactor,2)AS DECIMAL(6,2))
end
as UNIT_PUPFEE_Y
I am looking for a way where I can just write the calculation once and create both column aliases from that one statement eg:
,case when bi.PolicyFeeFactor = 0
then 0
else
CAST(ROUND(nb.AnnualPolicyFee * bi.PolicyFeeFactor,2)AS DECIMAL(6,2))
end
as UNIT_PUPFEE_Y, UNIT_POLFEE_Y
Wrap it inside a subquery, ex
SELECT Result AS UNIT_PUPFEE_Y,
Result AS UNIT_POLFEE_Y
FROM
(
SELECT CASE .... END AS Result
FROM tableName
) s
You may write like this,
SELECT *,UNIT_PULFEE_Y AS UNIT_PUPFEE_Y FROM
(SELECT *
,case when bi.PolicyFeeFactor = 0 then 0 else CAST(ROUND(nb.AnnualPolicyFee * bi.PolicyFeeFactor,2)AS DECIMAL(6,2)) end as UNIT_PULFEE_Y
FROM Table )A
Related
I have an SQL query joined on multiple tables (all INNER JOINS).
The below is an example of the query I am trying to run (the ? is to illustrate the position in which I presume the answer to my question will be rectified).
Case
(
SELECT Count(ID)
FROM CPD_Candidates cpdCan
WHERE
cpdCan.CandidateID = can.CandidateID
AND
(
cpdCan.DateEnded >= GETDATE()
OR
coalesce(cpdCan.DateEnded, '') = N'1-Jan-1900'
)
AND
cpdCan.Deleted <> 1
)
When ? > 0 then 'Bigger' else 'Equal or Smaller' End
)
The idea with the above is that instead of the ? the actual value I want to compare against would be Count(ID), if it's greater than 0 I want it to SELECT 'Bigger', otherwise it should SELECT 'Equal or Smaller'. So a more-accurate depiction of what I wish to run would be the below.
Case
(
SELECT Count(ID)
FROM CPD_Candidates cpdCan
WHERE
cpdCan.CandidateID = can.CandidateID
AND
(
cpdCan.DateEnded >= GETDATE()
OR
coalesce(cpdCan.DateEnded, '') = N'1-Jan-1900'
)
AND
cpdCan.Deleted <> 1
)
When
Count(cpdCan.ID) > 0 then 'Bigger' else 'Equal or Smaller' End
)
Of course there is a syntax error above but I am enquiring as to whether it is possible to compare like in the above SQL query structure but replacing Count(cpdCan.ID) > 0 with some other means to achieve that value & logic?
If this is un-achievable in SQL Server 2016 what other means would be a better solution to this XY?
I think that you mean:
case when
(
SELECT Count(ID)
FROM CPD_Candidates cpdCan
WHERE
cpdCan.CandidateID = can.CandidateID
AND (cpdCan.DateEnded >= GETDATE() OR coalesce(cpdCan.DateEnded, '') = N'1-Jan-1900')
AND cpdCan.Deleted <> 1
) > 0
then 'Bigger'
else 'Equal or Smaller'
End
I'm using proc sql, and using multiple case when statements to add columns with either a 0 or 1 if the condition is met. It's a big bottleneck right now since it has to scan through each id for each case when statement. So I'm trying to figure out a way to somehow nest the case statements to perform each iteration, instead of having to iterate for all case statements.
This is an example of my code that is taking too long right now.
SELECT *,
CASE WHEN loannumber IN (
SELECT loannumber FROM PREPAY_LOAN_IDS
) THEN 1
ELSE 0 END AS PREPAY_FLAG,
CASE WHEN loannumber IN (
SELECT loannumber FROM DPD_30_IDS
) THEN 1
ELSE 0 END AS DPD_30_FLAG,
CASE WHEN loannumber IN (
SELECT loannumber FROM DPD_60_IDS
) THEN 1
ELSE 0 END AS DPD_60_FLAG,
CASE WHEN loannumber IN (
SELECT loannumber FROM DPD_90_IDS
) THEN 1
ELSE 0 END AS DPD_90_FLAG,
CASE WHEN loannumber IN (
SELECT loannumber FROM DPD_120_IDS
) THEN 1
ELSE 0 END AS DPD_120_FLAG,
CASE WHEN loannumber IN (
SELECT loannumber FROM FORECLOSURE_IDS
) THEN 1
ELSE 0 END AS FORECLOSURE_FLAG
FROM(
SELECT *
FROM MORTGAGES
)
The below query will work faster than the one you have posted as the input table is not completely access to retrieve the results. Try running this query and see how it performs.
SELECT M.*,
CASE WHEN PLI.loannumber IS NOT NULL THEN 1
ELSE 0 END AS PREPAY_FLAG,
CASE WHEN D3I.loannumber IS NOT NULL THEN 1
ELSE 0 END AS DPD_30_FLAG,
CASE WHEN D6I.loannumber IS NOT NULL THEN 1
ELSE 0 END AS DPD_60_FLAG,
CASE WHEN D9I.loannumber IS NOT NULL THEN 1
ELSE 0 END AS DPD_90_FLAG,
CASE WHEN D12I.loannumber IS NOT NULL THEN 1
ELSE 0 END AS DPD_120_FLAG,
CASE WHEN FCI.loannumber IS NOT NULL THEN 1
ELSE 0 END AS FORECLOSURE_FLAG
FROM MORTGAGES M
LEFT JOIN
PREPAY_LOAN_IDS PLI
ON M.loannumber = PLI.loannumber
LEFT JOIN
DPD_30_IDS D3I
ON M.loannumber = D3I.loannumber
LEFT JOIN
DPD_30_IDS D6I
ON M.loannumber = D6I.loannumber
LEFT JOIN
DPD_90_IDS D9I
ON M.loannumber = D9I.loannumber
LEFT JOIN
DPD_90_IDS D12I
ON M.loannumber = D12I.loannumber
LEFT JOIN
FORECLOSURE_IDS FCI
ON M.loannumber = FCI.loannumber
;
Since you're using SAS, here's a data step alternative, assuming that each of your datasets is already either sorted by or has an index on loannumber:
data want;
merge MORTGAGES(in = Mortgages)
PREPAY_LOAN_IDS(in = PLIDs keep = loannumber)
/*etc*/
;
by loannumber;
if Mortgages;
PREPAY_FLAG = PLIDs;
/*etc*/
run;
N.B. You will get duplicated records from MORTGAGES if you have duplicates in any of your other tables.
i have a simple problem. i have a column with numbers. i need to filter them to even and odd numbers, but if a number is even than i need to copy or move it to "even-number-column" in the same table. if the number is odd then move it to "odd-number-column" in the same table.
this is my code:
select distinct all_numbers, even-number-column, odd-number-column
case when all_numbers%2=0
then UPDATE my_table SET even-number-column = all_numbers
else UPDATE my_table SET odd-number-column = all_numbers
end
from my_table ;
If you want a SELECT:
select
distinct all_numbers,
CASE
WHEN when all_numbers%2 = 0 THEN all_numbers
ELSE 0 -- or NULL
END as even-number-column,
CASE
WHEN when all_numbers%2 = 1 THEN all_numbers
ELSE 0 -- or NULL
END as odd-number-column
from my_table ;`
If you want an update
UPDATE my_table
SET
even-number-column = CASE
WHEN when all_numbers%2 = 0 THEN all_numbers
ELSE even-number-column -- or change for 0 or NULL
END,
odd-number-column = CASE
WHEN when all_numbers%2 = 1 THEN all_numbers
ELSE odd-number-column -- or change for 0 or NULL
END
Use an array to make it simple
update t
set
odd = (array[null, all_numbers])[all_numbers % 2 + 1],
even = (array[all_numbers, null])[all_numbers % 2 + 1]
Hi I have simply select and works great:
select 'CARAT Issue Open' issue_comment, i.issue_id, i.issue_status, i.issue_title, i.ISSUE_summary ,i.issue_description, i.severity,
gcrs.Area_name, gcrs.sector_name,
substr(gcrs.stream_name,1,case when instr(gcrs.stream_name,' (')=0 then 100 else instr(gcrs.stream_name,' (')-1 end) ISSUE_DIVISION,
case when gcrs.STREAM_NAME like 'NON-GT%' THEN 'NON-GT' ELSE gcrs.STREAM_NAME END as ISSUE_DIVISION_2
from table(f_carat_issues_as_of('31/MAR/2013')) i
inner join v_gcrs_with_stream gcrs on i.segment_id = gcrs.segment_id
where UPPER(ISSUE_STATUS) like '%OPEN%'
Now I want to call two columns:
ISSUE_DIVISION and ISSUE_DIVISION_2
if they are equal in new columns should be value 1 if are not equal should be 0,
how can I do it ?
my full code:
select 'CARAT Issue Open' issue_comment, i.issue_id, i.issue_status, i.issue_title, i.ISSUE_summary ,i.issue_description, i.severity,
gcrs.Area_name, gcrs.sector_name,
substr(gcrs.stream_name,1,case when instr(gcrs.stream_name,' (')=0 then 100 else instr(gcrs.stream_name,' (')-1 end) ISSUE_DIVISION,
case when gcrs.STREAM_NAME like 'NON-GT%' THEN 'NON-GT' ELSE gcrs.STREAM_NAME END as ISSUE_DIVISION_2
from table(f_carat_issues_as_of('31/MAR/2013')) i
inner join v_gcrs_with_stream gcrs on i.segment_id = gcrs.segment_id
where UPPER(ISSUE_STATUS) like '%OPEN%' and
CASE WHEN ISSUE_DIVISION = ISSUE_DIVISION_2 THEN
CASE WHEN ISSUE_DIVISION is null then "Null Value found"
Else 1 End
ELSE 0 END As Issue_Division_Result
but I get error on line:
ELSE 0 END As Issue_Division_Result
ORA-00920: invalid relational operator :(
SELECT (CASE WHEN ISSUE_DIVISION = ISSUE_DIVISION_2 THEN 1 ELSE 0 END) AS ISSUES
-- <add any columns to outer select from inner query>
FROM
( -- your query here --
select 'CARAT Issue Open' issue_comment, ...., ...,
substr(gcrs.stream_name,1,case when instr(gcrs.stream_name,' (')=0 then 100 else instr(gcrs.stream_name,' (')-1 end) ISSUE_DIVISION,
case when gcrs.STREAM_NAME like 'NON-GT%' THEN 'NON-GT' ELSE gcrs.STREAM_NAME END as ISSUE_DIVISION_2
from ....
where UPPER(ISSUE_STATUS) like '%OPEN%'
)
WHERE... -- optional --
So simple you can use case statement here.
CASE WHEN ISSUE_DIVISION = ISSUE_DIVISION_2 THEN
CASE WHEN ISSUE_DIVISION is null then "Null Value found" //give your option
Else 1 End
ELSE 0 END As Issue_Division_Result
In one line, answer is as below;
[ CASE WHEN COLUMN_NAME = 'VALUE' THEN 'SHOW_THIS' ELSE 'SHOW_OTHER' END as ALIAS ]
use the variable, Oracle does not support SQL in that context without an INTO. With a properly named variable your code will be more legible anyway.
SELECT MyTable.Name,
(
SELECT CASE WHEN ISNULL(SUM(TotalDays), 0) <= 0 THEN 0
ELSE SUM(TotalDays)
END AS Total
FROM Application AS Applications
WHERE (ID = MyTable.id)
) - MIN(Assignments) AS Excesses
FROM MyTable
The above TSQL statement is a subquery in a main query. When i run it, if TotalDays is NULL or <=0, then Total is set to 0 (zero).
What i would like to do here is to set the result of the whole query(Excesses) to 0. I want (Excesses) which is the result of Total - Min(Assignments) to be set to 0 if its NULL or <=0.
I want the CASE WHEN to apply to the whole query but am struggling to get it right.
SELECT
MyTable.Name,
CASE WHEN
0 < (SELECT SUM(TotalDays) FROM Application WHERE ID = MyTable.id) - MIN(Assignments)
THEN
(SELECT SUM(TotalDays) FROM Application WHERE ID = MyTable.id) - MIN(Assignments)
ELSE
0
END AS [Excesses]
FROM
MyTable
Note: MS SQL Server won't exexute the two correlated-sub-queries independantly, it will infact recognise that they are the same and re-use the results.
Alternative:
SELECT
MyTable.Name,
CASE WHEN
0 < SUM([application].TotalDays) - MIN([MyTable].Assignments)
THEN
SUM([application].TotalDays) - MIN([MyTable].Assignments)
ELSE
0 -- If either aggregate is NULL, 0 will still be returned
END AS [Excesses]
FROM
MyTable
LEFT JOIN
Application
ON [application].ID = [MyTable].id
SELECT MyTable.Name, CASE WHEN ISNULL(SUM(TotalDays), 0) <= 0 THEN 0 ELSE SUM(TotalDays) END AS Total
FROM Application AS Applications
JOIN MyTable
ON Applications.id = mytable.id
GROUP BY
MyTable.id, MyTable.name
HAVING CASE WHEN ISNULL(SUM(TotalDays), 0) <= 0 THEN 0 ELSE SUM(TotalDays) END > 0