MySQL - help with IF... ELSE usage within query - mysql

I need to add an if/else stament inside a MySQL query but can't get it to work.
Below is an example with pseudo-code of what I want to accomplish.
SELECT *
FROM calendar
WHERE calendar.alert = 1
IF calendar.repeat = 0 THEN HAVING calendar.UTC_1 > UNIX_TIMESTAMP();
ELSE "get all records regardless of calendar.repeat value";
END IF;
Any suggestions to make this happen? I couldn't find the correct syntax for this MySQL IF ELSE.
Thanks for helping!

SELECT *
FROM calendar
WHERE calendar.alert = 1
AND CASE
WHEN `repeat` =0 THEN UTC_1 > UNIX_TIMESTAMP()
ELSE 1=1 END;
You can use IF-ELSE only inside the body of stored procedure/trigger. You can use IF(condition, value_if_condition_is_true, value_if_condition_is_false) in SELECT, but I prefer CASE(you can easily rewrite the query above to
.... AND IF(`repeat` = 0, UTC_1>UNIX_TIMESTAMP(),1=1)

Not sure I got the syntax all right here, but I like the idea of somethign like this. In my opinion it is much easier to look at in the future and see the two groups you're grabbing with the following example. I'm not educated on efficiency of case vs union in MySQL but it seems to me like the case would be less efficient as well. Maybe someone can answer that for sure?
SELECT *
FROM calendar
WHERE
calendar.alert = 1
AND calendar.repeat = 0
AND calendar.UTC_1 > UNIX_TIMTESTAMP();
UNION
SELECT *
FROM calendar
WHERE
calendar.alert = 1
AND calendar.repeat != 0

Related

Need to change SQL query for a temporary result

I need a temporary result for just a query. If substring condition true, I want to lower its car_performance value by %10 (car_performance = car_performance*0.9;) and compare this substring true cars against others BUT ONLY FOR THE QUERY, I don't want to change the real data in SQL database.
So I thought I need to get this data to a new temporary table with lowered car_performance values but I can't figure out how to write it.
SELECT *
FROM car_list
IF SUBSTRING(car_model, 9, 1) = '3'`
car_performance = car_performance*0.9;
ORDER BY car_performance ???
I'm not sure I did correctly understand you. Correct me if I am wrong. Do you want to select all cars that respect condition SUBSTRING(car_model,9,1) = 3 and print their performance like 0.9*performance? If so, you can use this statement:
SELECT car_model, car_performance*0.9 as car_performance
FROM car_list
WHERE SUBSTRING(car_model, 9, 1) = '3'
I also recommend you to take a SQL course. It is easier and faster to understand after you learn the basics. There are a lot of great free resources online.
I suppose you need a comparison for whole set of cars depending on a condition for some of them, and leaving the rest as they are. If so, CASE WHEN ... THEN .. ELSE ... conditional statement will do the trick such as
SELECT CASE WHEN SUBSTRING(car_model, 9, 1) = '3'
THEN car_performance * .9
ELSE car_performance
END AS car_performance
FROM car_list
ORDER BY car_performance

How to hide the Repeated record in SQL

Using this query:
SELECT
linerbltbl.billofladingid,
linerbltbl.grossweighttotal,
linerb‌​ltbl.netweighttotal,
linerblwisecontainerdetailstbl.containertype,
linerblwisecont‌​ainerdetailstbl.cont‌​ainernumber,
linerblwisecontainerdetailstbl.sealnumber,
linerblwisecontain‌​erdetailstbl.princip‌​lecharge
FROM linerbltbl,
linerblwisecontainerdetailstbl
WHERE linerbltbl.shippername IS NOT NULL
AND linerbltbl.billofladingid =
linerblwisecontainerdetailstbl.bil‌​lofladingid
See this image. It shows what my output IS and what I would like it to be.
You will note that the repeated data is blanked out. Is there a way to do this in my query?
First of all, I think you are going about this wrong. While you CAN do this from within the query itself (see this page) you are probably better off doing it in whatever is consuming the output. For example, if you are taking this data and pasting it into MS Excel, you could check out this post which does is via conditional formatting. If you are consuming it from inside code, you can add logic to handle it there (since I don't know what you are going to do with it, it's hard to add any examples).
But, if you insist on doing it from within SQL it's going to be something to this effect (borrowing from the linked example):
;with t as
(SELECT
linerbltbl.billofladingid,
linerbltbl.grossweighttotal,
linerb‌​ltbl.netweighttotal,
linerblwisecontainerdetailstbl.containertype,
linerblwisecont‌​ainerdetailstbl.cont‌​ainernumber,
linerblwisecontainerdetailstbl.sealnumber,
linerblwisecontain‌​erdetailstbl.princip‌​lecharge
FROM linerbltbl,
linerblwisecontainerdetailstbl
WHERE linerbltbl.shippername IS NOT NULL
AND linerbltbl.billofladingid =
linerblwisecontainerdetailstbl.bil‌​lofladingid
)
SELECT
CASE WHEN RR = 1 THEN billofladingid ELSE '' END BillOfLadingID,
CASE WHEN RR = 1 THEN grossweighttotal ELSE '' END GrossWeight,
CASE WHEN RR = 1 THEN netweighttotal ELSE '' END NetWeight,
containertype,
cont‌​ainernumber,
sealnumber,
princip‌​lecharge
FROM
(SELECT (ROW_NUMBER() OVER(PARTITION BY billofladingid ORDER BY billofladingid, grossweighttotal)) [RR], *
FROM t) SUBQUERY1

Little bit of trouble with my MySQL query

My MySQL Query
Ok so I'm trying to add another column (leave_remaining) that will display that if the leave_status is 'ok' then the leave_remaining will show the number of leave days that employee has left. I keep getting errors with this. What is the right syntax here? Thank you
This works:
select id,leave_started,leave_ended,no_of_leave_allowed,
leave_ended-leave_started AS no_of_leaves_taken,
if (leave_ended-leave_started >no_of_leave_allowed,
'leave exceeded','ok')as leave_status
from leave_taken;
This does not:
if (leave_status,'ok',
(no_leave_allowed-no_leaves_taken))as leave_remaining
from leave_taken;
select * from leave_taken;
If I'm understanding you properly, I think you want this:
SELECT
id, leave_started, leave_ended, no_of_leave_allowed,
(leave_ended - leave_started) AS no_of_leaves_taken,
IF(
(leave_ended - leave_started) > no_of_leave_allowed,
'leave exceeded',
'ok'
) AS leave_status,
IF (
(leave_ended - leave_started) > no_of_leave_allowed,
(no_of_leave_allowed - (leave_ended - leave_started)),
0
) AS leave_remaining
FROM leave_taken;
Though not sure how you have defined leave_started and leave_ended that you can subtract them like that...
http://sqlfiddle.com/#!9/16cdb3/6
SELECT has to be before the IF, altough you are not doing anything.
The correct statement is
SELECT something as alias, something_else as alias_else, if(,,) as alias_if
FROM table
WHERE where = clause
When you have to use some statement (IF or CASE for example), that result in a field, it has to be inside a select.

SELECT ALL in a CASE inside a SELECT

i'm using Pentaho and I was wondering if it's possible to do some query like this :
SELECT Something
FROM Somewhere
WHERE (CASE WHEN condition1 = 0 THEN Option IN (Parameter) ELSE
(Option IN (SELECT Option FROM Somewhere_else)) END);
If you want some precision, i want to select everything if my condition is not respected in my WHERE clause (the thing i want to select in the where is different from the original select).
Don't hesitate to ask me for my approach and of course to answer !
Thank you !
PS: The Parameter is a Pentaho parameter which represents here an array
Just use regular conditions:
SELECT Something
FROM Somewhere
WHERE (condition1 = 0 AND Option IN (Parameter))
OR (condition1 != 0 AND Option IN (SELECT Option FROM Somewhere_else));
You should try following,
SELECT Something
FROM Somewhere
WHERE
1 = case when condition1 = 0 THEN
case when Option IN (Parameter) then 1 else 0 end
else
case when Option IN (SELECT Option FROM Somewhere_else) then 1 else 0 end
end
CASE is irrelevant in your statement, and is pretty much irrelevant in the WHERE clause at all.
Use simple conditions as suggested by #X.L.Ant, or you could do some nasty joining like
SELECT *
FROM table a
INNER JOIN somewhere ON (option = 0 AND a.id = somewhere.id)
INNER JOIN parameter ON (option != 0 AND a.id = parameter.id)
Assuming your parameter is somewhat a table.

Need help in writing Efficient SQL query

I have the following query, written inside perl script:
insert into #temp_table
select distinct bv.port,bv.sip,avg(bv.bv) bv, isnull(avg(bv.book_sum),0) book_sum,
avg(bv.book_tot) book_tot,
check_null = case when bv.book_sum = null then 0 else 1 end
from table_bv bv, table_group pge, table_master sm
where pge.a_p_g = '$val'
and pge.p_c = bv.port
and bv.r = '$r'
and bv.effective_date = '$date'
and sm.sip = bv.sip
query continued -- need help below (can some one help me make this efficient, or rewriting, I am thinking its wrong)
and ((sm.s_g = 'FE')OR(sm.s_g='CH')OR(sm.s_g='FX')
OR(sm.s_g='SH')OR(sm.s_g='FD')OR(sm.s_g='EY')
OR ((sm.s_t = 'TA' OR sm.s_t='ON')))
query continued below
group by bv.port,bv.sip
query ends
explanation: some $val that contain sip with
s_g ('FE','CH','FX','SH','FD','EY') and
s_t ('TA','ON') have book_sum as null. The temp_table does not take null values,
hence I am inserting them as zero ( isnull(avg(bv.book_sum),0) ) where ever it encounters a null for the following s_g and s_m ONLY.
I have tried making the query as follows but it made my script to stop wroking:
and sm.s_g in ('FE', 'CH','FX','SH','FD','EY')
or sm.s_t in ('TA','ON')`
I know this should be a comment, but I don't have the rep. To me, it looks like it's hanging because you lost your grouping at the end. I think it should be:
and (
sm.s_g in ('FE', 'CH','FX','SH','FD','EY')
or
sm.s_t in ('TA','ON')
)
Note the parentheses. Otherwise, you're asking for all of the earlier conditions, OR that sm.s_t is one of TA or ON, which is a much larger set than you're anticipating, which may cause it to spin.