How can i do something like this ?
SELECT (IF(SUM(Costo) > 0) SUM(Costo) ELSE 0) AS Expr1
FROM TDP_NotaSpeseSezB
You want to use a CASE statement.
Select
CASE WHEN SUM(Costo) > 0 THEN SUM(Costo)
ELSE 0
END 'Expr1'
FROM
TDP_NotaSpeseSezB
You can use case statement like this:
SELECT case when sum(Costo)> 0 then sum(Costo)
else 0 end as Expr1
FROM TDP_NotaSpeseSezB
CASE (Transact-SQL)
SELECT CASE WHEN SUM(Costo) > 0 THEN SUM(Costo) ELSE 0 END AS Expr1
FROM TDP_NotaSpeseSezB
Other major engines support this syntax:
SELECT GREATEST(SUM(Costo), 0)
FROM TDP_NotaSpeseSezB
SQL Server, however, does not.
Related
I may be missing something obvious! Thanks in advance for any help.
I am trying to use a CASE statement in an inline SQL Statement. I only want to evaluate the expression once, so I am looking to put the expression in the CASE section, and then evaluate the result in each WHEN. Here is the example:
SELECT
MyTable.ColumnA,
CASE DateDiff(d, MyTable.MyDate, getDate())
WHEN <= 0 THEN 'bad'
WHEN BETWEEN 1 AND 15 THEN 'reasonable'
ELSE 'good'
END as MyCalculatedColumn,
MyTable.SomeOtherColumn
I know I can do this:
CASE
WHEN DateDiff(d, MyTable.MyDate, getDate()) <= 0 THEN 'bad'
WHEN DateDiff(d, MyTable.MyDate, getDate()) BETWEEN 1 AND 15 THEN 'reasonable'
ELSE 'good'
END
But in my first example, SQL does not seem to like this statement:
WHEN <= 0 THEN 'bad'
Note that the statement is inline with other SQL, so I can't do something like:
DECLARE #DaysDiff bigint
SET #DaysDiff = DateDiff(d, MyTable.MyDate, getDate())
CASE #DaysDiff
WHEN <= 0 THEN 'bad'
WHEN BETWEEN 1 AND 15 THEN 'reasonable'
ELSE 'good'
END
My actual DateDiff expression is much more complex and I only want to maintain its logic, and have it evaluated, only once.
Thanks again...
You can use apply for this purpose:
SELECT MyTable.ColumnA,
(CASE WHEN day_diff <= 0 THEN 'bad'
WHEN BETWEEN 1 AND 15 THEN 'reasonable'
ELSE 'good'
END) as MyCalculatedColumn,
MyTable.SomeOtherColumn
FROM MyTable CROSS APPLY
(VALUES (DateDiff(day, MyTable.MyDate, getDate()))) v(day_diff)
APPLY is a very handy way to add calculated values into a statement. Because they are defined in the FROM clause, they can be used in SELECT, WHERE, and GROUP BY clauses where column aliases would not be recognized.
I see your problem. CASE expression WHEN value can only do an equality check
You could try using a CTE (Common Table Expression), do everything except the case statement in the CTE and then put the CASE in the final SELECT at the end. I'm not sure whether it will prevent the expression being evaluated twice - thats kindof the optimisers problem, not yours (thats how I like to think about it)
WITH cteMyComplexThing AS(
SELECT MyTable.ColumnA,
DateDiff(d, MyTable.MyDate, getDate()) as ComplexThing,
MyTable.SomeOtherColumn
FROM MyTable
)
SELECT
ColumnA,
CASE
WHEN ComplexThing <= 0 THEN 'bad'
WHEN ComplexThing BETWEEN 1 AND 15 THEN 'reasonable'
ELSE 'good'
END as MyCalculatedColumn,
SomeOtherColumn
FROM cteMyComplexThing
The WHEN clause in a CASE statement needs both sides of the condition. <=0 cannot stand by itself.
CASE #DaysDiff
WHEN ? <= 0 THEN 'bad'
WHEN BETWEEN 1 AND 15 THEN 'reasonable'
ELSE 'good'
END
I need some help with case statement.
my code:
select c.name, c.date_entered, i.transaction, i.planned_date,
case (c.date_entered - i.planned_date)
when (c.date_entered - i.planned_date) > 0 then 'YES'
when (c.date_entered - i.planned_date) < 0 then 'NO'
end RESPECT
from company c,transaction i
but it give me error ORA-00907; missing right parenthesis
thank you to help me with.
select c.name, c.date_entered, i.transaction, i.planned_date,
case when c.date_entered - i.planned_date > 0
then 'YES'
when c.date_entered - i.planned_date < 0
then 'NO'
end as RESPECT
from company c, transaction i
You should also think about the output of when c.date_entered - i.planned_date = 0 or change one of the cases to <= or >=.
How can i shorten the following select statement?
create or replace view V_AMV_PLG_QUOTES_50_MS as
select
sum(NVL(ASK_SIZE,0)) as ASK_VOLUME,
CASE WHEN
sum(CASE WHEN NVL(ASK_SIZE,0)=0 THEN CASE WHEN BASE_CURR_ASK_PRICE=0 THEN 0 ELSE 1 END ELSE ASK_SIZE END)=0 THEN 1
ELSE sum(CASE WHEN NVL(ASK_SIZE,0)=0 THEN CASE WHEN BASE_CURR_ASK_PRICE=0 THEN 0 ELSE 1 END ELSE ASK_SIZE END) END as ASK_PRICE,
EXCHANGE_SK as EXCHANGE_SK,
PRODUCT_SK as PRODUCT_SK,
BUSINESS_DATE as BUSINESS_DATE
from
S_AMV_PLG_QUOTE_AGG quotes
where NVL(BASE_CURR_ASK_PRICE ,0) > 0
group by
EXCHANGE_SK,
PRODUCT_SK,
BUSINESS_DATE
Notice the very long calculation appears twice.. Can i insert it into a variable somehow? And just use the CASE operator on the Variable? (Notice we have a sum function there..)
You can't use create and use a variable within a view. If you just want to avoid repeating the nested case statement, you could move it (and the NVL) into an in-line view:
select
sum(MY_ASK_SIZE) as ASK_VOLUME,
CASE WHEN sum(MY_ASK_PRICE)=0 THEN 1
ELSE sum(MY_ASK_PRICE)
END as ASK_PRICE,
EXCHANGE_SK as EXCHANGE_SK,
PRODUCT_SK as PRODUCT_SK,
BUSINESS_DATE as BUSINESS_DATE
from (
select
EXCHANGE_SK, PRODUCT_SK, BUSINESS_DATE,
NVL(ASK_SIZE,0) as MY_ASK_SIZE,
CASE WHEN NVL(ASK_SIZE,0)=0 THEN
CASE WHEN BASE_CURR_ASK_PRICE=0 THEN 0 ELSE 1 END
ELSE ASK_SIZE
END AS MY_ASK_PRICE
from S_AMV_PLG_QUOTE_AGG quotes
where NVL(BASE_CURR_ASK_PRICE ,0) > 0
)
group by
EXCHANGE_SK,
PRODUCT_SK,
BUSINESS_DATE;
The NVL and case are performed once, and aliased as MY_ASK_SIZE and MY_ASK_PRICE respectively; and those aliases are then used in the outer query, including within the sum.
If you want to avoid repeating the SUM too, move that into the in-line view as well, along with the group-by clause:
select
ASK_VOLUME as ASK_VOLUME,
CASE WHEN ASK_PRICE=0 THEN 1
ELSE ASK_PRICE
END as ASK_PRICE,
EXCHANGE_SK as EXCHANGE_SK,
PRODUCT_SK as PRODUCT_SK,
BUSINESS_DATE as BUSINESS_DATE
from (
select
EXCHANGE_SK, PRODUCT_SK, BUSINESS_DATE,
SUM(NVL(ASK_SIZE,0)) as ASK_VOLUME,
SUM(CASE WHEN NVL(ASK_SIZE,0)=0 THEN
CASE WHEN BASE_CURR_ASK_PRICE=0 THEN 0 ELSE 1 END
ELSE ASK_SIZE
END) AS ASK_PRICE
from S_AMV_PLG_QUOTE_AGG quotes
where NVL(BASE_CURR_ASK_PRICE ,0) > 0
group by
EXCHANGE_SK,
PRODUCT_SK,
BUSINESS_DATE
);
Most of your column aliases are redundant but I've stuck with your pattern.
This is largely cosmetic though; Oracle's optimiser is likely to be clever enough to only perform the actual calculation once anyway, so I wouldn't expect to see much (or any) performance difference.
I used creation of a simple ifZeroReturnOne function:
CREATE OR REPLACE FUNCTION ifZeroReturnOne (expr IN NUMBER)
RETURN NUMBER
IS retval NUMBER;
BEGIN
SELECT CASE WHEN expr=0 THEN 1
ELSE expr END
INTO retval
FROM DUAL;
RETURN (retval);
END;
Than I used in the query:
select sum(NVL(ASK_SIZE,0)) as ASK_VOLUME,
ifZeroReturnOne (sum(CASE WHEN NVL(ASK_SIZE,0)=0 THEN CASE WHEN BASE_CURR_ASK_PRICE=0 THEN 0 ELSE 1 END ELSE ASK_SIZE END) as ASK_PRICE,
EXCHANGE_SK as EXCHANGE_SK,
etc...............
Let me know if you have better suggestions
Is it possible to use case with and in count
SELECT branches.NAME AS agence,
count(
CASE loanstatus
WHEN '1'
AND Datepart(month,loanaccount.issuedate)= 2 THEN 1
ELSE NULL
END )AS nombre_de_credits_demande ,
count(
CASE loanstatus
WHEN '2' datepart(month,loanaccount.chargeoffdate)= 2 THEN 1
ELSE NULL
END )AS nombre_de_credits_approuve
please help me
You can use it with count(). I prefer sum():
select Branches.Name as Agence,
sum(case when LoanStatus = '1' and
datepart(MONTH, LoanAccount.IssueDate) = 2
then 1 else 0
end ) as Nombre_de_Crédits_Demandé ,
sum(case when LoanStatus = '2' and
datepart(MONTH, LoanAccount.IssueDate) = 2
then 1 else 0
end ) as Nombre_de_Crédits_Approuvé
The issue with your code was not the count() versus sum() it is the mixing of two different case syntaxes. When you use case <var> when <val>, you cannot include any other conditions. Just use when with the full conditions that you want.
And, if you like, you can use count() instead of sum().
And, for conciseness, I prefer the month() function:
select Branches.Name as Agence,
sum(case when LoanStatus = '1' and MONTH(LoanAccount.IssueDate) = 2
then 1 else 0
end ) as Nombre_de_Crédits_Demandé ,
sum(case when LoanStatus = '2' and MONTH(LoanAccount.IssueDate) = 2
then 1 else 0
end ) as Nombre_de_Crédits_Approuvé
you can achieve your goal through this query.
select
branches.name as agence
,(select COUNT(1) from <table_name> where loginstatus=1 and Datepart(month,loanaccount.issuedate)= 2) as nombre_de_credits_demande
,(select COUNT(1) from <table_name> where loginstatus=2 and Datepart(month,loanaccount.issuedate)= 2) as AS nombre_de_credits_approuve
from <Table_name>
I have a SQL statement that determines the number of days between two dates. If the difference is negative, the statement needs to select 0. This statement works but I was wondering if it is possible to assign the value of datediff("D",GETDATE(),dbo.tblKBX_Reward.validdate) to a # variable so I don't have to call it twice.
SELECT CASE
WHEN datediff("D",GETDATE(),dbo.tblKBX_Reward.validdate) < 0 THEN 0
ELSE datediff("D",GETDATE(),dbo.tblKBX_Reward.validdate)
END from ...
Please don't ask why I am calculating this value using SQL instead of in code.
Thanks
You could move the case statement inside the calculation, like this:
Select DateDiff("D", GetDate(), Case When YourColumn > GetDate()
Then YourColumn
Else GetDate()
End)
You can write a higher level SELECT something like this.
SELECT CASE
WHEN diff_date < 0 THEN 0
ELSE diff_date
END
FROM (
SELECT datediff("D",GETDATE(),dbo.tblKBX_Reward.validdate) AS diff_date
from ...
)
If you are selecting more than one row, then you can't assign it to a variable. In your case, you can use a derived table or a CTE:
SELECT Cols,
CASE
WHEN DiffDates < 0 THEN 0
ELSE DiffDates
END DiffDates
FROM ( SELECT Cols, datediff("D",GETDATE(),dbo.tblKBX_Reward.validdate) DiffDates
FROM dbo.tblKBX_Reward) A
Or:
;WITH CTE AS
(
SELECT Cols, datediff("D",GETDATE(),dbo.tblKBX_Reward.validdate) DiffDates
FROM dbo.tblKBX_Reward
)
SELECT Cols,
CASE
WHEN DiffDates < 0 THEN 0
ELSE DiffDates
END DiffDates
FROM CTE
SELECT
CASE WHEN daydiff < 0 THEN 0 ELSE daydiff END
FROM your tables/joins
CROSS APPLY (
SELECT DATEDIFF(DAY, GETDATE(), dbo.tblKBX_Reward.validdate)
) x (daydiff)
WHERE …
You could use a CTE:
WITH cte_dateDiffs (RewardId, dateDiff)
AS (
SELECT RewardId, datediff("D",GETDATE(), validdate) FROM dbo.tblKBX_Reward
)
SELECT CASE
WHEN dd.dateDiff < 0 THEN 0
ELSE dd.dateDiff
END
FROM dbo.tblKBX_Reward r
INNER JOIN cte_dateDiffs dd ON r.RewardId == dd.RewardId
...