We have a table that has either NULL or "Accepted" as values. My query returns about 250 rows.
If I add a where condition of -
AND Description = 'Accepted'
my 250 rows return in 2 seconds.
However, if I add a where condition of -
ISNULL(Description, '') = 'Accepted'
my 250 rows return in 47 seconds.
Has anyone encountered performance issues with using the ISNULL function? Unfortunately I am programatically limited to having to use ISNULL at this point.
When you include a field inside of a function, it changes how the optimizer has to run and forces it to ignore indexes.
see here: What makes a SQL statement sargable?
You can also bypass the functions entirely by using:
WHERE (Description = 'Accepted' OR Description IS NULL)
Using
ISNULL(Description, '') = 'Accepted'
in your where condition doesnt make any sense in this case. If the description is null, the original where clause of
AND Description = 'Accepted'
will still suffice.
You are basically comparing '' with 'Accepted' in every row where the description is null.
Please elaborate on what you are trying to accomplish with the query, i think you might be going in the wrong direction.
If you are trying to use this in the WHERE condition, use IS NULL, not ISNULL
SELECT field FROM table WHERE description is null
or the opposite
SELECT field FROM table WHERE NOT description is null
Related
Hopefully this is a simple one but I am most likely over complicating this for myself. Purpose of this code is to find previous operation name within a specified list of operations that is still open and returning it. If it's closed to say 'CLOSED'.
So far I'm using subquery to get the correct operation name, as expected I'm getting some null results which indicates to me that operation is closed. I wanted to wrap my subquery into a case statement to say something along the lines of CASE WHEN it's null then 'CLOSED' else operation_name end.
(select work_center_no
from shop_order_operation
where order_no = so.order_no
and release_no = so.release_no
and sequence_no = so.sequence_no
and work_center_no in ('CNC','EXPF','LS3M','LS4M','LS6M','PLAS','SAW','TBPL','EXSAW')
and oper_status_code in ('Released','In Process') order by operation_no fetch first 1 row only )
Above is my subquery. Hope this makes sense.
Thanks!
K
You can nicely default a value using IFNULL, just change your select clause to this:
select IFNULL(work_center_no, 'CLOSED')
Consider the following table:
SELECT id, Bill_Freq, Paid_From, Paid_To, Paid_Dt, rev_code FROM psr_20160708091408;
The requirement is to fetch the row which has rev_code populated with the string **SUM**.
I've also noticed that for every row with rev_code populated as **SUM** its Bill_Freq won't be either null or zero.
So I wrote two queries to fetch the row with the lowest id
Query based on string check in where clause:
select
min(id) as head_id,
bill_freq,
Paid_From,
Paid_To,
Paid_Dt
from
`psr_20160708091408` where rev_code = "**SUM**";
Query based on true condition:
select
min(id) as head_id,
bill_freq,
Paid_From,
Paid_To,
Paid_Dt
from
`psr_20160708091408` where bill_freq;
I haven't seen anyone use the second type, would like to know its reliability and circumstance of failure.
If by "second type" you mean a where clause with no explicit condition, then there is a good reason why you do not see it.
The SQL standard -- and most databases -- require explicit conditions in the where. MySQL allows the shorthand that you use but it really means:
where not billing_freq <=> 0
or equivalently:
where billing_freq <> 0 or billing_freq is null
(The <=> is the null-safe comparison operator.
The more important issue with your query is the min(). I presume that you actually want this:
select p.*
from psr_20160708091408 p
where rev_code = '**SUM**'
order by id
limit 1;
Also, you should use single quotes as string delimiters. That is the ANSI standard and there is rarely any reason to use double quotes.
Actually you can use the second type of query, but as your requirement is based on rev_code, it is always good to have condition with rev_code, because of 2 reasons
Bill_Freq having no NUlls or Zeros might be assumption based on current data
Even if it is true, in future, your application logic might change and it might have a scenario having NULL or zero, which will break your logic in future.
So my suggestion is to use first query with Rev_code
Please try to use below query
select
id,
bill_freq,
Paid_From,
Paid_To,
Paid_Dt
from
`psr_20160708091408` where rev_code = "**SUM**" ORDER BY ASC LIMIT 0,1;
Thanks.
The requirement says it itself.
The requirement is to fetch the row which has rev_code populated with
the string '**SUM**'
In the scenario that bill_freq IS NOT NULL and rev_code is populated with
the string '**SUM**' then your logic will obviously fail.
Go for
where rev_code = "**SUM**";
I'm currently doing this via two separate queries from PHP, but would love to optimize and somehow in a single query.
First query..
SELECT `referrer`
FROM `tbl_traffic_log`
WHERE `domain` = 'mysite.com'
AND `referrer` != '$referringDomain'
AND CASE WHEN `clicks_in_unique`=0 THEN 2 ELSE `clicks_out_unique`/`clicks_in_unique` END < 1.4
ORDER BY RAND()
LIMIT 1
..and if mysql_num_rows shows no results, I do a second query to try again and check if there are any results minus the referrer != 'partner1.com' part.
The code is basically trying to find a random trade partner who ISN'T the partner who sent that click, but if there are no matches, as a last resort it's ok to send back, provided it matches the other criteria.
I'm pretty sure there is a way to do this, but just can't find a way after searching (probably because I'm not understanding the problem enough to type in the right thing).
Any other critique of the query is welcome as well.
Thank you :)
I think you can do this like this:
SELECT `referrer`
FROM `tbl_traffic_log`
WHERE `domain` = 'mysite.com'
AND CASE WHEN `clicks_in_unique`=0 THEN 2 ELSE `clicks_out_unique`/`clicks_in_unique` END < 1.4
ORDER BY `referrer` != '$referringDomain' desc, RAND()
LIMIT 1
The idea is to put the condition in the order by. The condition (in MySQL) evaluates to either 0 or 1, so we want where the condition is true first (hence the desc). It then chooses a random row. If there are no rows where the condition is true, then it chooses a random row.
I have a column that has null values as well as other values such as 'deactivated'. I am trying to build a query that says "WHERE field <> 'deactivated" but it returns an empty result set. From my research it seems to be because it can't compare to the null values. But I haven't been able to figure out how to get around it.
Thanks
As it seems that you want nulls included in the result set, the correct condition would be
WHERE field <> 'deactivated' OR field IS NULL
Try looking for NULL specifically:
WHERE field <> 'deactivated' OR field IS NULL
FYI, you must use IS NOT and not a comparision operator because NULL doesn't equal anything. Even another NULL;
Since you're using MySQL, you can use the "equal to" operator:
WHERE NOT(field <=> 'deactivated')
In other, more SQL-standards compliant databases, you'd write
WHERE field IS DISTINCT FROM 'deactivated'
I have recently written a blog post on the DISTINCT predicate and how it is supported in various databases.
You can use MySQL's "null-safe equal" operator <=>:
WHERE NOT field <=> 'deactivated'
Can anyone help me understand or post any ideas concerning this where clause?
sql was here
I've changed the table name, but other than that, any idea what the developer was trying to do here?
There is nothing else after that, that's the where clause.
If (table.date_field = (select max(table2.exit_date) from table as table2)) is null the it'll return 1=1, which basically means there's no where clause at all.
Now let's look into that nasty expression. I can only assume that if "a = b" is not true then that's also equivalent to null, otherwise it seems like the first branch would always happen. It looks like it's trying to say "if the latest exit date is equal to the date field, select those, otherwise have no where clause". However, I don't think that this will work at all. It really looks like either way, each row will be selected.
The MySQL ifnull function returns the first argument if it is not null, otherwise the second argument. This looks like it tries to compare table.date_field to the max(table2.exit_date), and return true if the comarison was not possible due to nulls.
It looks to me like he is trying to find the row where table.date_field is equal to the maximum of table.exit_data. There is a check for null which I think would happen in any of these cases:
table is empty
all rows in table have exit_data set to NULL
table.date_field is NULL for the row in question
In any of these three cases, the row will be returned. I don't understand why he uses the string '1=1' instead of, to give some examples: 1=1, 1 or true, but it appears to work fine. In the first case I assume that there will be no rows in the result set anyway (depending on the rest of the query) so he was probably trying to handle one of the other two cases - I'd guess the last one.
This is only an explanation of what is happening. To understand why he is doing this, it would help if you gave a little more context.
MySQL is nonstandard in that true is really equal to the numeric value 1. Any expression that evaluates to true, or any nonzero value, satisfies the condition.
mysql> CREATE TABLE foo AS SELECT 1=1 AS f;
mysql> SHOW CREATE TABLE foo;
CREATE TABLE `foo` (
`f` INT NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
So the following WHERE clause is legal in MySQL, but not in most other SQL databases:
... WHERE 1;
Some people use 1=1 as a placeholder condition meaning true, but putting it in a string is meaningless because SQL expressions have no equivalent to an eval() function as other languages have. In this case, the leading character 1 in the string is implicitly cast to a numeric value 1, which is interpreted as true in MySQL. So it probably works as intended, but kind of by accident.
The use of IFNULL() is so that if either date_field or MAX(exit_date) is NULL, it returns the row. If you didn't use this function, then anything = NULL would evaluate as unknown, which means the row would not be returned.
It says basically if table.date_field = max exit date or if max exit_date is null or table.date_field is null return true. Will return false if max exit_date is not null and table.date_field is not null but they do not equal.