Conditional WHERE statements based on parameters? - mysql

I am trying to conditionally create a WHERE clause in a stored procedure. It is to act as a filter on a boolean column and there's only two outcomes I want - either only take the true values, or take all of them (no situation where I only need the false values).
The clause I am trying to use is this -
WHERE
(#customerInactive = -1 OR `listcustomers`.`active` = 1)
with the idea either the parameter is a -1 (no filter) or we do have a filter and should do listcustomers.active = 1.
I tried being more explicit as well
WHERE
((#customerInactive = 1 AND `listcustomers`.`active` = 1) OR
(#customerInactive <> 1 AND 1=1))
The second one ends up not returning anything then. How can I fix this?
This is in a stored procedure, using MySQL 5.6.
Edit: Given that I've been told my first query should do it, but it always returns listcustomers.active = 1, is this possibly a type issue? I made customerInactive a int(11). I also just tried it as a bit(1) but I am still getting the same issue, no matter my paraemter I get the TRUE filter. Or in the case of the second query, no results.
Edit 2: I don't think this should matter but the final result is the union of multiple tables of which I am going to have to do this same sort of filtering. The whole SQL query can be seen here - https://pastebin.com/6wL4ZtnF

Considering your comments, this is the results you want depending of customerInactive and the value of listcustomers.active
#customerInactive | listcustomers.active | result
------------------+----------------------+--------
0 | 0 | 1
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0
This is a NAND (Not And) that can be written such way in SQL :
NOT (#customerInactive = 1 AND listcustomers.active = 1)

The correct answer is that I confused parameters and user defined variables. I am passing in customerInactive as a parameter to the stored procedure, so I should reference it directly by name. Using the # made it look like a User defined variable which was NOT defined, hence the constant failing of my initial equality and why the true filter was always on. Thanks everyone.

Related

SQL : SELECT SUM WHERE CONDITION

I've got some troubles about SQL request :
I have a table like this table data image
I would like to create a view from this table to get :
Time_A : SUM of a column (total_time_taken) WHERE column (is_radiant)=1
Time_B : SUM of the same column (total_time_taken) WHERE column (is_radiant)=0
Time_AB : SUM of the column (total_time_taken) WHERE column (is_radiant)=0 OR (is_radiant)=1
SELECT
SUM(`matchpickban_radiant`.`total_time_taken`) AS `draft_time_radiant`,
SUM(`matchpickban_dire`.`total_time_taken`) AS `draft_time_radiant`
FROM
(`matchpickban` AS `matchpickban_radiant`
JOIN `matchpickban` AS `matchpickban_dire` ON ((`matchpickban_dire`.`idmatchpickban` = `matchpickban_radiant`.`idmatchpickban`)))
WHERE
`matchpickban_radiant`.`is_radiant` = 1
AND `matchpickban_dire`.`is_radiant` = 0
Actually I can run this request without syntax error but the result is NULL cause no data can be equal to 0 AND equal to 1 in the same time, obviously...
Also, I don't know if it's possible to make a JOIN the table to itself as I did (matchpickban JOIN matchpickban).
If syntax is correct I need to place my WHERE CONDITION away but don't know how, is it possible to replace it with 2 IF statement (IF is_radiant=0 SUM(...))
Thx for reading and helping me about this issue I got !
If you need more info about table or request I will give you all you need !
No need for a self-join or complex logic, you can just use conditional aggregation, which consists in using conditional expression within aggregate functions.
In MySQL, you could go:
select
sum(is_radiant * total_time_taken) time_a,
sum((1 - is_radiant) * total_time_taken) time_b,
sum(total_time_taken) time_ab
from matchpickban
where is_radiant in (0, 1)
This works because is_radiant is made of 0/1 values only - so this simplifies the logic. A more canonical way to phrase the conditional sums would be:
sum(case when is_radiant = 1 then total_time_taken else 0 end) time_a,
sum(case when is_radiant = 0 then total_time_taken else 0 end) time_b,

MYSQL WHERE id = 0 it should show total result

SQLFiddle
In this fiddle example i m trying to use WHERE o.d_id = 1 or 2,3,4 etc but if i use d_id= 0 it should show the total result or we can say the where clause should not work if d_id = 0.
You can do a conditional style WHERE clause like this....
WHERE (?inputvalue = 0 OR ?inputvalue = d_id)
In this case the ?inputvalue is whatever search term you want. You'll provide it from your programming language.
edit Notice that in many queries you can specify an input value just once. For example, if all you want is WHERE d_id = 17 that's easy to specify. You just put the 17 in and you're done.
But, if you follow my suggestion you need to repeat the input value. You need WHERE (0 = 17 OR d_id = 17). That will, when you give it 17, filter your result set to find the seventeens.
And, if you give it 0, like this WHERE ( 0 = 0 OR d_id = 0 ) it will find all results, not filtering on just the zeroes. That's good because there aren't any zeros.
Probably, that's not how WHERE works. If you write a statement like WHERE id = 0, you ask your database to return just the rows where the id column is set to 0. If you want your database to return all values, you have to skip this condition completly

Add Column in Table with conditional in block WHERE

I was doing a query with MySQL to save all objects returned, but I'd like identify these objects based in statements of the block WHERE, that is, if determined object to satisfy the specific characteristic I'd like create one column and in this column I assignment the value 0 or 1 in the row corresponding the object if it satisfy or not satisfy these characteristic.
This is my script:
SELECT
s.id, al.ID, al.j, al.k, al.r, gal.i
FROM
datas as al
WHERE
AND s.id = al.ID
AND al.j between 1 and 1
AND al.k BETWEEN 15 and 16
AND al.r BETWEEN 67 and 72
The script above is working perfectly and I can to save all objects which it return.
So, I'd like to know if is there a way add in the query above, on block WHERE, the following statement,
( Flags & (dbo.environment('cool') +
dbo.environment('ok') -
dbo.environment('source')) ) = 25
and ((al_pp x al_pp1)-0.5/3=11
and determined the objects that satisfy or not these condition with 0 or 1 in a new column created in Table saved.
I read some tutorials about this and saw some attempts with IF, CASE, ADD COLUMN or WHEN, but none of these solved.
Thanks in advance
MySQL has if function, see here
So you can simply use it in your query:
SELECT IF(( Flags & (dbo.fPhotoFlags('SATURATED') +
dbo.fPhotoFlags('BRIGHT') +
dbo.fPhotoFlags('EDGE')) ) = 0
and petroRad_r < 18
and ((colc_u - colc_g) - (psfMag_u - psfMag_g)) < -0.4
, 1 --// VALUE IF TRUE
, 0 --// VALUE IF FALSE
) as conditional_column, ... rest of your query

SQL Query, Subquery won't return data

Problem: My Query returns NULL
Potential issues: Subquery formatted wrong and only works if some data I want to sort out is in the dataset.
Example of today's code:
SELECT production_order
,SUM(total_working_time_h) - (SELECT SUM(total_working_time_h) FROM {$table} WHERE production_order = '$production_order' AND (station = '出货检验 | OQC' OR production_type = 'Rework')) AS total_working_time_h_edit
,SUM(no_of_defects) AS no_of_defects_during_production
FROM {$table}
WHERE production_order = '$production_order'
This works great as long as I have either "Rework" and/or "'出货检验 | OQC'" logged in my database for this production order. If not, I won't get any data at all but NULL. So my problem is somewhere in my subquery I think:
SELECT SUM(total_working_time_h) FROM {$table} WHERE production_order = '$production_order' AND (station = '出货检验 | OQC' OR production_type = 'Rework')
I've tried adding a "0" to make sure it's get 0 and not NULL without success like follows:
(0 + SELECT SUM(total_working_time_h) FROM {$table} WHERE production_order = '$production_order' AND (station = '出货检验 | OQC' OR production_type = 'Rework')
Example dataset formated as text:
production_order part_nr station total_working_time_h
26135 129-108816B-UL 压接 | Crimping 1.42
26135 129-108816B 线束组装 | Harness Assembling 7.67
26135 129-108816 测试 | Testing 0.83
26135 129-108816B 外观全检 | Appearance inspection 0.83
Gives this output:
production_order,total_working_time_h_edit
26135, NULL
I want this output:
production_order,total_working_time_h_edit
26135, 10,45
If my dataset hold the station I want to sort out or the production_type I want to sort out everything works as it should. But if both of those is missing in the dataset it returns NULL, since what I think is because the subquery returns 0.
An example of different datasets I'm using. If I have the data marked with green cells in the dataset it will work. If not, I get the return NULL as above.
So how to make my subquery to not return NULL?
Managed to solve the question myself.
Problem: Subquery returned NULL instead of 0.
Solution: Added COALESCE(,0) to my sub querys function SUM() like this:
COALESCE(SUM(total_working_time_h),0)
By doing so it returns 0 instead of NULL when the SUM() actually wants to return NULL. That solved my problem.

PHP MYSQL Compare rows when defining WHERE statement

Lets say I have these DB rows
id | storage | used | status
1 - 100 - 0 - 1
2 - 1000 - 5000 - 1
I need to compare the rows "storage" and "used"
I want to select rows WHERE status = 1 and Column"storage" > Column"used".
I tried WHERE status = '1' AND storage > used
It should report back row id #1, but it doesnt.
Well, WHERE status=1 AND storage > used is correct. If you tried it and didn't get back the row with id=1 there's something wrong with your data.
Are storage and used numeric columns? Or are they stored as a VARCHAR (or, gasp, TEXT)? If so, you won't be able to compare them quite the way you want, and will first have to convert or cast them to numeric types. It would be better to change the type to actually be numeric (i.e., INT or DECIMAL or whichever other type is appropriate).
SELECT * FROM `table` WHERE status = '1' AND storage > used
should give you the right solution, like VoteyDisciple mentioned, make sure status and used are both of numeric type.
you can use SELECT * FROMtableWHERE status = '1' AND storage > used but the data type of the storage and used must be NUMERIC not VARCHAR.
if Still you didn't get correct ans then it should be problem with your data storage structure.
Thanks!