Mysql: how send two parameters in constraction IF() - mysql

I want set two conditions in query, but query does not work.
SELECT IF((I.num_ip <> '100.100.100.100') &&
(I.num_ip <> '100.100.100.101'), I.num_ip, null) AS num_ip
FROM company C, computers
WHERE C.id_ip = I.id_ip
AND C.date_conn = '2015-08-12'
GROUP BY num_ip

It can be written in other way as well using CASE expression like
Select case when I.num_ip not in ('100.100.100.100', '100.100.100.101')
then I.num_ip else null end) as num_ip
From company C
join computers I on C.id_ip = I.id_ip
Where C.date_conn = '2015-08-12';
** Not sure though why you need a GROUP BY here.

IN your query there are multiple issues
Condition (I.num_ip <> '100.100.100.100') && (I.num_ip <> '100.100.100.101) wont be true almost all the time since num_ip will have value either 100.100.100.100' or '100.100.100.101'
there is one ' missing at end on 101.
please go through "http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html" for detailed use of control flows.
make sure num_ip is nullable.
there are 2 where in query
also if you have group by then you should use aggregate functions COUNT, SUM, AVG, etc. please go through http://www.tutorialspoint.com/mysql/mysql-group-by-clause.htm
Computer table doesn't have alias used as I
Select if(((I.num_ip <> '100.100.100.100') || (I.num_ip <> '100.100.100.101')), I.num_ip, null) as num_ip
From company C, computers I
Where C.id_ip = I.id_ip
and C.date_conn = '2015-08-12'
--Group by num_ip
Thanks,
Tanmay

Your query syntax is invalid, syntax highlighting should warn you.
This one should be correct:
SELECT IF((I.num_ip <> '100.100.100.100') &&
(I.num_ip <> '100.100.100.101'), I.num_ip, null) AS num_ip
FROM company C, computers
WHERE C.id_ip = I.id_ip AND C.date_conn = '2015-08-12'
GROUP BY num_ip
Moreover, computers table is in FROM clause but seems not to be used. Is it normal ?

Related

Using case statement or IF inside a WHERE clause

I have several stored procedures that are almost identical but have some different AND parts inside a WHERE clause.
Based on a variable deptname, I want to add additional AND/OR conditions to my already existing WHERE clause. So kind of like IF/CASE WHEN on the part that is different.
Think about it as string concatenation
query_string = 'WHERE a= XYZ AND B= 123"
if deptname = a: query_string + "AND additional conditions for dept a"
else if deptname = b:query_string + "AND additional conditions for dept b"
What is the appropriate way to use a variable?
here is some pseudo code of what I am trying to do
SELECT
personID AS pid,
personcode,
persondeptcode,
more_fields AS fields
FROM
TABLE_XYZ
WHERE
--shared parts
personcode = 'C'
AND
persondeptcode = 'MAJ'
--- NOW the different part
IF #deptname = "deptA"
AND
(
PROGRAM_LDESCR IN
(
'prog1',
'prog2',
'prog3'
)
OR
aprogram IN ('aprogram1')
OR
(aprogram IN ('aprogram2') AND PLAN_LDESCR IN ('plan123'))
);
--- THIS IS A DIFFERENT DEPT SO WE HAVE DIFFERENT AND PART
ELSE IF #deptname = "deptB"
(
PROGRAM_LDESCR IN
(
'1234'
)
OR
aprogram IN ('a1234')
);
You can use a CASE expression in this case, the important thing is to make sure you have an ELSE clause to ensure the expression remains true if #deptname is not one of the two values with extra conditions:
WHERE personcode = 'C'
AND persondeptcode = 'MAJ'
AND (CASE #deptname
WHEN "deptA" THEN PROGRAM_LDESCR IN ('prog1', 'prog2', 'prog3')
OR aprogram IN ('aprogram1')
OR aprogram IN ('aprogram2') AND PLAN_LDESCR IN ('plan123')
WHEN "deptB" THEN PROGRAM_LDESCR IN ('1234')
OR aprogram IN ('a1234')
ELSE 1
END)
Here is a simple demo of a CASE expression used in this fashion.
You seem to want something like:
AND
(#deptname = 'dept123' AND (PROGRAM_LDESCR IN ('1234') OR aprogram IN ('a1234')) OR
#deptname <> 'dept123'
)
To combine the last part of the WHERE clause (if I'm understanding your commented-code correctly), you could do something like the following:
SELECT
personID AS pid,
personcode,
persondeptcode,
more_fields AS fields
FROM
TABLE_XYZ
WHERE
personcode = 'C'
AND persondeptcode = 'MAJ'
AND (
(#deptname="deptA" AND (PROGRAM_LDESCR IN ('prog1', 'prog2', 'prog3') OR aprogram IN ('aprogram1') OR (aprogram IN ('aprogram2') AND PLAN_LDESCR IN ('plan123'))))
OR
(#deptname="deptB" AND (PROGRAM_LDESCR IN ('1234') OR aprogram IN ('a1234'))
)
Normally you would use the WHERE clause to filter out unnecessary rows of data and a CASE statement if you wanted to actually change the value in the SELECT statement (I rarely see CASE statements outside a SELECT clause, unless it is doing something like a complex sort).

Subquery returned more than 1 value.4...Different query

Hello I have this query that i am trying to execute and i keep getting this error "Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.", Kindly help please.
DECLARE #NUMCOUNT BIT
Select #NUMCOUNT = (SELECT
CASE WHEN
(SELECT COUNT(R5REQUISLINES.RQL_REQ)
WHERE R5REQUISLINES.RQL_STATUS IN ('A')
) IN
(SELECT COUNT(R5REQUISLINES.RQL_REQ)
WHERE R5REQUISLINES.RQL_STATUS IN ( 'A','C') ) THEN 1 else 0 END AS NUMCOUNT1
FROM R5REQUISLINES JOIN
R5REQUISITIONS ON R5REQUISLINES.RQL_REQ = R5REQUISITIONS.REQ_CODE
GROUP BY R5REQUISLINES.RQL_REQ, R5REQUISITIONS.REQ_CODE,R5REQUISLINES.RQL_STATUS
)
IF #NUMCOUNT = '1'
begin
UPDATE R5REQUISITIONS
SET R5REQUISITIONS.REQ_STATUS = 'CP'
end
Ok, it sounds like what you actually want to do is update R5REQUISITIONS when there is no RQL_STATUS = 'C' in R5REQUISLINES, since you said you want to count the records where the RQL_STATUS is A and where it's A or C, and then do the update if the counts are the same.. You can greatly simplify this task with the following query:
UPDATE r5
SET r5.REQ_STATUS = 'CP'
FROM R5REQUISITIONS r5
WHERE NOT EXISTS (SELECT 1 FROM R5REQUISLINES r5q WHERE r5q.RQL_REQ = r5.REQ_CODE AND r5q.RQL_STATUS = 'C')
Your 'SELECT CASE' is returning more than 1 record, so it can't be assigned to #NUMBER. Either fix the sub-query to only return the record your looking for or hack it to return only 1 with a 'LIMIT 1' qualification.
I don't know what your data looks like so I can't tell you why your case subquery returns more records than you think it should.
Try running this and see what it returns, that will probably tell you wall you need to know:
SELECT
CASE WHEN
(SELECT COUNT(R5REQUISLINES.RQL_REQ)
WHERE R5REQUISLINES.RQL_STATUS IN ('A')
) IN
(SELECT COUNT(R5REQUISLINES.RQL_REQ)
WHERE R5REQUISLINES.RQL_STATUS IN ( 'A','C')
)
THEN 1
ELSE 0
END AS NUMCOUNT1
FROM R5REQUISLINES JOIN
R5REQUISITIONS ON R5REQUISLINES.RQL_REQ = R5REQUISITIONS.REQ_CODE
GROUP BY R5REQUISLINES.RQL_REQ, R5REQUISITIONS.REQ_CODE,R5REQUISLINES.RQL_STATUS
If there is more than 1 row returned, that's where your problem is.

using if statement in mysql query

I would like to use if statement in sql query :
what I want :
if(tractions_delivery.send_date_id !=0 ){
date_send_commodities.id = tractions_delivery.send_date_id
}
my query :
from
tractions_delivery,user_address,province,city,date_send_commodities,users
WHERE
tractions_delivery.tr_id = $tr_id
AND
tractions_delivery.address_id = user_address.id
AND
user_address.province_id = province.id
AND
user_address.city_id = city.id
AND
//not work
(tractions_delivery.send_date_id IS NOT 0 date_send_commodities.id = tractions_delivery.send_date_id)
AND
users.id = user_address.user_id
You could use the CASE-statement
SELECT
*
FROM
tractions_delivery,
user_address,
province,
city,
date_send_commodities,users
WHERE
tractions_delivery.tr_id = $tr_id AND
tractions_delivery.address_id = user_address.id AND
user_address.province_id = province.id AND
user_address.city_id = city.id AND
CASE WHEN tractions_delivery.send_date_id != 0 THEN date_send_commodities.id = tractions_delivery.send_date_id ELSE 1=1 END AND
users.id = user_address.user_id
You can only use if statements in stored procedures or functions. If you just write a sql statement unfortunately you cannot use if statements around the query. But you can use logic in the query itself, e.g.:
SELECT CASE WHEN col1 = col2 THEN'col1 equals col2' else 'col1 doesnt equal col2' ELSE
FROM table1
So around doesnt work, but in the field list you can create CASE WHEN ELSE END logic.
CASE or IF() operators can be of help.
Examples,
SELECT (CASE 1 WHEN 1 THEN 'One' WHEN 2 THEN 'Two' ELSE 'More' END) 'Result';
OR
SELECT IF(1=1, 'One', 'Two') 'Result';
These CASE and IF() operators can be used in the SELECT clause to conditionally interpret column values and return in the resultset.
Note: Do not confuse CASE operator here with 'CASE conditional syntax block' that ends with END CASE.

MySQL IF ELSEIF in select query

I'm trying to select different prices of a product based on the quantity that user chooses.
This is the query I'm working on (it has a syntax error):
select id,
(SELECT
IF(qty_1<='23',price,1)
ELSEIF(('23'>qty_1 && qty_2<='23'),price_2,1)
ELSEIF(('23'>qty_2 && qty_3<='23'),price_3,1)
ELSEIF('23'>qty_3,price_4,1)
END IF) as total
from product;
You have what you have used in stored procedures like this for reference, but they are not intended to be used as you have now. You can use IF as shown by duskwuff. But a Case statement is better for eyes. Like this:
select id,
(
CASE
WHEN qty_1 <= '23' THEN price
WHEN '23' > qty_1 && qty_2 <= '23' THEN price_2
WHEN '23' > qty_2 && qty_3 <= '23' THEN price_3
WHEN '23' > qty_3 THEN price_4
ELSE 1
END) AS total
from product;
This looks cleaner. I suppose you do not require the inner SELECT anyway..
IF() in MySQL is a ternary function, not a control structure -- if the condition in the first argument is true, it returns the second argument; otherwise, it returns the third argument. There is no corresponding ELSEIF() function or END IF keyword.
The closest equivalent to what you've got would be something like:
IF(qty_1<='23', price,
IF('23'>qty_1 && qty_2<='23', price_2,
IF('23'>qty_2 && qty_3<='23', price_3,
IF('23'>qty_3, price_4, 1)
)
)
)
The conditions don't all make sense to me (it looks as though some of them may be inadvertently reversed?), but without knowing what exactly you're trying to accomplish, it's hard for me to fix that.
I found a bug in MySQL 5.1.72 when using the nested if() functions .... the value of column variables (e.g. qty_1) is blank inside the second if(), rendering it useless. Use the following construct instead:
case
when qty_1<='23' then price
when '23'>qty_1 && qty_2<='23' then price_2
when '23'>qty_2 && qty_3<='23' then price_3
when '23'>qty_3 then price_4
else 1
end
For your question :
SELECT id,
IF(qty_1 <= '23', price,
IF(('23' > qty_1 && qty_2 <= '23'), price_2,
IF(('23' > qty_2 && qty_3 <= '23'), price_3,
IF(('23' > qty_2 && qty_3<='23'), price_3,
IF('23' > qty_3, price_4, 1))))) as total
FROM product;
You can use the if - else control structure or the IF function in MySQL.
Reference:
http://easysolutionweb.com/sql-pl-sql/how-to-use-if-and-else-in-mysql/
As per Nawfal's answer, IF statements need to be in a procedure. I found this post that shows a brilliant example of using your script in a procedure while still developing and testing. Basically, you create, call then drop the procedure:
https://gist.github.com/jeremyjarrell/6083251

mysql error: sub-query returns more than 1 row

I am using two tables here projections_report p and access_rights a. I can't find out why I am getting the error:
subquery returns more than one row
(case when paramChannel='AllC' then p.gl_sal_chan in
(case when dc_lob=0 then (select distinct pr.gl_sal_chan from
projections_report pr) else (select distinct pr1.gl_sal_chan
from projections_report pr1 where pr1.gl_sal_chan
in (select distinct a.gl_sal_chan from access_rights
a where a.userid= paramUserId)) end)
else p.gl_sal_chan = paramChannel end)
I tried using all and any keywords. Please help.
Thanks in advance.
USE LIMIT in sub queries to return only one record as you are using distinct, it might return more than one record
I tried to do it in another way and got it right. Firstly I changed the statement in else condition of second case statement to
(select distinct gl_sal_chan from access_rights where userid = paramUserid)
as both return the same result(my bad) and secondly I changed the entire condition to
(case when (paramChannel = 'AllC' && dc_lob = 0) then '%' = '%' else
(case when (paramChannel='AllC' && dc_lob != 0) then
gl_sal_chan in (select distinct gl_sal_chan from access_rights where userid = paramUserid)
else gl_sal_chan= paramChannel end)end)
Anyway Thanks #all :)