I have implemented multiple conditions in case statement as below,
select officied from budgettable
where budgetid = case #budgetid when 7 then 7
when 7 then 8
when 7 then 10
when 8 then 6
end
but it didn't give me any result. If I pass budget-Id as 7 the query should return 8,10,7 budget id's. Anything wrong in the above query?
I suspect that you want something like this:
where budgetid = #budgetid or
(#budgetid = 7 and budgetid in (7, 8, 10)) or
(#budgetid = 8 and budgetid = 6)
Your query is failing because for all values of #budgetid other than 7 or 8, the case returns NULL -- which is treated as false.
One option is to use the case as a boolean expression, returning 1 when your conditions are met:
select officied from budgettable
where 1 = case
when #budgetid = budgetid then 1
when #budgetid = 7 and budgetid in (7,8,10) then 1
when #budgetid = 8 and budgetid in (6,8) then 1
end
This expands the results returned by #budgetid 7 to include 8 and 10.
This is no answer. I just want to show how CASE WHEN works, so you see your mistake. Your query evaluates case #budgetidas follows:
when 7 then 7 => take a 7 for a #budgetid 7
when 7 then 8 => ignored, because we already said to take 7 for a #budgetid 7
when 7 then 10 => ignored, because we already said to take 7 for a #budgetid 7
when 8 then 6 => take a 6 for a #budgetid 8
end => no else here, so any other #budgetid results in NULL.
You then compare the result with = budgetid. This is never true for NULL. So you end up with:
where (#budgetid = 7 and budgetid = 7)
or (#budgetid = 8 and budgetid = 6)
This will work !!
SELECT
officied
FROM
budgettable
WHERE
1 = 1
AND
1 = CASE
WHEN
#budgetid = budgetid THEN 1
WHEN
(#budgetid = 7 AND budgetid IN (7,8,10)) THEN 1
WHEN
(#budgetid = 8 AND budgetid IN (6,8) THEN) 1
END
Better solution : Add a new column is_budget_calculated (Data type BIT) and update it as 0 and remaining as 1.
Related
I hope someone can help me here.
I'm writing a CASE in impala to find the missed lines in the table.
However, I need to write my example below to WHEN 1000 = 999. Instead of writing 1000 CASE lines, is there a more efficient and quicker solution that requires less code? It would help me a lot. Thank you.
CASE WHEN dif_tradecount = 2 THEN 1
WHEN dif_tradecount = 3 THEN 2
WHEN dif_tradecount = 4 THEN 3
WHEN dif_tradecount = 5 THEN 4
WHEN dif_tradecount = 6 THEN 5
WHEN dif_tradecount = 7 THEN 6
WHEN dif_tradecount = 8 THEN 7
WHEN dif_tradecount = 9 THEN 8
WHEN dif_tradecount = 10 THEN 9
WHEN dif_tradecount = 11 THEN 10
WHEN dif_tradecount = 12 THEN 11 .....
ELSE null
END AS missed_messages
if i got your task correct:
CASE
WHEN dif_tradecount > 1 and dif_tradecount<=1000 THEN dif_tradecount-1
ELSE null
END AS missed_messages
You could do:
(case when dif_tradecount between 2 and 1000
then dif_tradecount - 1
end) as missed_messages
I wonder why the case is necessary. Perhaps:
nullif(dif_tradecount - 1, 0) as missed_messages
would also work.
I am trying to dynamically modify my where clause by using a declared variable in a case statement above. Forgive me if there is a simple answer to this that I'm missing, but I'm entirely self taught and still have a lot to learn. Here's a sample of the syntax. I am not going to bother with the entire syntax of the statement, just enough that hopefully you will understand what I'm trying to do.
declare #myvar1 double
declare #myvar2 double
SELECT
q1.host_po_nbr,
q1.etd,
CASE
WHEN WEEKDAY(TODAY) = 1 Then 11
WHEN WEEKDAY(TODAY) = 2 Then 12
WHEN WEEKDAY(TODAY) = 3 Then 13
WHEN WEEKDAY(TODAY) = 4 Then 14
WHEN WEEKDAY(TODAY) = 5 Then 15
END #myvar1,
CASE
WHEN WEEKDAY(TODAY) = 1 Then 5
WHEN WEEKDAY(TODAY) = 2 Then 6
WHEN WEEKDAY(TODAY) = 3 Then 7
WHEN WEEKDAY(TODAY) = 4 Then 8
WHEN WEEKDAY(TODAY) = 5 Then 9
END #myvar2,
FROM q1
WHERE q1.etd BETWEEN today - #myvar1 AND today - #myvar2
I'm assuming that you're only using variables to try and reference the calculation in the SELECT clause from your WHERE clause. You can't reference aliases from the SELECT in your WHERE clause (at least not in most SQL systems). The reason is that The WHERE clause is evaluated before the select, so those aliases do not exist at the time the WHERE clause is being evaluated. You can use a subquery, however:
SELECT * FFROM
(SELECT
q1.host_po_nbr,
q1.etd,
CASE
WHEN WEEKDAY(TODAY) = 1 Then 11
WHEN WEEKDAY(TODAY) = 1 Then 12
WHEN WEEKDAY(TODAY) = 1 Then 13
WHEN WEEKDAY(TODAY) = 1 Then 14
WHEN WEEKDAY(TODAY) = 1 Then 15
END myvar1,
CASE
WHEN WEEKDAY(TODAY) = 1 Then 5
WHEN WEEKDAY(TODAY) = 1 Then 6
WHEN WEEKDAY(TODAY) = 1 Then 7
WHEN WEEKDAY(TODAY) = 1 Then 8
WHEN WEEKDAY(TODAY) = 1 Then 9
END myvar2,
FROM q1
) q
WHERE etd BETWEEN today - myvar1 AND today - myvar2
Try this:
SELECT
q1.host_po_nbr,
q1.etd,
CASE
WHEN WEEKDAY(TODAY) = 1 Then 11
WHEN WEEKDAY(TODAY) = 1 Then 12
WHEN WEEKDAY(TODAY) = 1 Then 13
WHEN WEEKDAY(TODAY) = 1 Then 14
WHEN WEEKDAY(TODAY) = 1 Then 15
END myvar1,
CASE
WHEN WEEKDAY(TODAY) = 1 Then 5
WHEN WEEKDAY(TODAY) = 1 Then 6
WHEN WEEKDAY(TODAY) = 1 Then 7
WHEN WEEKDAY(TODAY) = 1 Then 8
WHEN WEEKDAY(TODAY) = 1 Then 9
END myvar2,
FROM q1
HAVING q1.etd BETWEEN today - myvar1 AND today - myvar2
This, however, could be inefficient. If this does not solve your problem, post more details, in particular, your table structure (SHOW CREATE TABLE) and a good description of what you are trying to achieve.
I am trying to figure how I could do this where I have a table as follows:
ID FKeyID Complete
1 6 1
2 6 0
3 6 0
4 7 0
5 8 0
6 8 0
I want to create a function to return 1 or true if any FKeyID for example 6 has a value of 1 in complete column and 0 if it does not.
This is a function that takes fKey value and should return 1 or 0 based on that.
So in above basically if my FKeyID is 6 return 1 because complete column is 1 in one of the rows, and 0 for FKeyID 8 because none of values in column complete is 1.
CREATE function [dbo].f_x
(
#FKeyID int
)
RETURNS bit
as
begin
return case when exists
(select 1 from test where Complete = 1 and FKeyID = #FKeyID)
then 1 else 0 end
end
Hello i was wondering is there a way to round up to a multiple of 5 in SQL?
For example this only rounds up to ten if i set #Order = 8 or 9 but when it's 7 or 6 it rounds down to 5, i need it to round up to 10 when it's 6 or 7.
declare #Order int
set #Order = 7
select round(cast(#Order as float)/cast(5 as float),0)*5
I need
#Order = 1,2,3,4 to round up to 5
#Order = 6,7,8,9 to round up to 10
#Order = 11,12,13,14 to round up to 15
Use the CEILING function
SELECT CEILING(#Order / 5.0) * 5
SELECT CEILING(#Order / 5.0) * 5
If you don't want to use built-in functions and avoid using CASE statements, have a look at this one:
select #Order, 5 * ((#Order+4) / 5)
For first 20 number result will look like:
number rounded
----------- -----------
1 5
2 5
3 5
4 5
5 5
6 10
7 10
8 10
9 10
10 10
11 15
12 15
13 15
14 15
15 15
16 20
17 20
18 20
19 20
20 20
Here is another approach to the same problem.
declare #num as int
set #num = 12
select #num + case when #num%5=0 then 0 else 5-(#num%5) end
So in my app I am trying to do a simple math in one of my methods without using a ton of if/else statements.
So I have an integer named 'StartInt' which is at max 13. Now what I need to get is FinishInt an integer that will be the result of this pattern:
StartInt: 13 FinishInt: 1
StartInt: 12 FinishInt: 2
StartInt: 11 FinishInt: 3
etc... all the way down until StartInt is 1 and FinishInt is 13. Anyway how would I accomplish this? I know this must be simple but I am just not that great in Math! :)
All the way down until StartInt is 0 and FinishInt is 13. Anyway how
would I accomplish this?
That won't quite work if startInt = 13 gives finishInt = 1 and you want a finishInt to increment 1 for each decrement of startInt. Check out the following table:
13 1
12 2
11 3
10 4
9 5
8 6
7 7
6 8
5 9
4 10
3 11
2 12
1 13
So you're off by 1 at either the beginning or end of your sequence. Nevertheless, it looks like you want something like this:
(int) calculateFinish(int startInt)
{
int finishInt = -1;
if (startInt >= 0 && startInt <= 13) {
finishInt = 14 - startInt;
}
return finishInt;
}
That'd give a value of 14 for finishInt when startInt = 0.