How to use "IS" and "=" in MySQL in the right way - mysql

Trying to figure out when to use "is", "=" since it seems like these two don't work the same way in SQL.
I've tried to switch these two in different commands, and I thought I'd receive the same result, but seems like SQL would only recognize one of them with particular functions
WHERE event_date **=** '2013-12-22'
And I tried to use "IS" instead of "=" for the above command
WHERE event_date **IS** '2013-12-22'
Then I got an error code, also in another practice question. I wanted to use "IS" before "BETWEEN", that failed too.
WHERE
affected_customers BETWEEN 50000
AND 150000
I tried to put
WHERE
affected_customers IS BETWEEN 50000
AND 150000

IS word cannot just be added before another operator.
IS operator is used for checking value against boolean
IS NULL and IS NOT NULL are used for checking values against NULLs.

SQL operators don't necessarily need to be use like how you construct an English sentence.
IS operator is usually use with the NULL operator, hence IS NULL and IS NOT NULL - used to checked if a value is NULL.
affected_customers BETWEEN 50000 AND 150000 is enough and logical, you'll get use to it as you go along with your programming life.
Best of luck to your journey!

Related

How to treat null as 0 when use addition in sql with out IFNULL

I have a query which add many thing in a expression. Like this select a+b+c+d+e ....
But some of them may be null and I want to treat null value as 0.
I know I can use IFNULL like select ifnull(a,0)+ifnull(b,0)+ifnull(c,0)+ifnull(d,0)+ifnull(e,0), but I have many queries and this seems laboursome.
Is there some easy way like a function to achieve the same result?
As mentioned in the comments, you will need to use indeed either IFNULL or IF.
However, if you have lots of them, and you are in control of the schema, I would suggest defining your fields as .. NOT NULL DEFAULT 0 (explicit default is good). This way, you will not need IFNULL any longer.

Format a string with a decimal separator between every 3 digits

In a MySQL database, I have a string like 123456789. I want to add a decimal separator between every 3 digits, and thus turn it into 123.456.789.
How can I do this?
If you are using MySQL 8.0+, it is possible to use the REGEXP_REPLACE function:
SELECT REGEXP_REPLACE(YOUR_COLUMN, '([:digit:]{3})(?!$)', '$0.');
It adds a dot for each group of 3 digits, excepted for the last one.
Here are some examples:
123456789 returns 123.456.789
1234567891 returns 123.456.789.1
12345678910 returns 123.456.789.12
You can try it out on this DB Fiddle and you can change the regular expression to fit what you need.
However, this approach is probably not the best in terms of performance. If your query is called a lot of times, your database server will suffer since calculation is centralized on it. As #xNoJustice said, it is better to handle this string operation in the client part, where it will be divided between every client execution.
Use FORMAT() function with suitable locale.
fiddle, which shows all suitable locales.

MySQL syntax error for converting and formatting a date

I'm having trouble with a line of code in MySQL. I am attempting to write the following line of code into a select statement that I already have and that works. I have a comma both before and after the line to handle the field prior to this and after this. The support_due_date field is a date field.
ISNULL(DATE_FORMAT(support_due_date, '%m/%d/%Y'), '01/01/1900') as support_due_date2
I'm getting a syntax error. The support_due_date field has some null values and some date values. I am wanting to format the field to have a M/D/YYYY format and if the field is Null change it to 01/01/1900. What am I doing wrong? Any help would be appreciated. I'm using version 5.2.47 if that helps.
ISNULL() by itself merely evaluates to true or false based on the argument passed; I believe your syntax error is due to attempting to pass 2 comma-separated arguments to that function. What you're actually looking for is, I think, something more like if(isnull(support_due_date), '01/01/1900', date_format(support_due_date, '%m/%d/%Y')) as support_due_date2 .
The documentation for control flow statements (including if()) is here.
That said, eggyal makes a good point about magic values in their comment to your question - imho there is a time and a place for both approaches, just something to consider.

Performance in rlike expression or alternate query?

I am doing a series of updates on some tables after I import them from tab-separated values. The data comes with dates in a format I do not like. I bring them in as strings, manipulate them so that they are in the same format as MySQL dates and then convert the column. Or sometimes not, but I want them to be like MySQL dates even if they are strings.
They start out like '1/4/2013 12:00:00 AM' or '11/4/2012 2:37:45 PM'.
I turn these into '2013-01-04' (usually, since times are present even when the original schema clearly specifies dates only) and '2012-11-04 14:37:45'.
I am using rlike. And this does not use indexes? Wow. That sucks.
But already, for each column, I have to use 4 updates to handle the different cases ('1/7', '2/13', '11/2', '12/24'). If I did these using like, it might take 16 different updates for each column....
And, if I am seeing it right, I cannot even get positional parameters out of the rlike expression, yes? You know, the part of the expression wrapped in parentheses that becomes $1 or $2....
So, it seems as though it is going to be quicker to pre-process the tsv file with perl. Really? Wow. Again, this sucks.
Any other suggestions? I cannot have this taking 3 hours every time I need to pull in the data.
Recall the classic 1997 quote from Jamie Zawinski:
Some people, when confronted with a problem, think "I know, I'll use regular expressions."
Now they have two problems.
Have you tried using STR_TO_DATE()? This is exactly for parsing nonstandard date/time strings into canonical datetime values.
If you try parsing with STR_TO_DATE() and the string doesn't match the expected format, the function returns NULL.
So you could try parsing in different formats, and return the first one that gives a non-null result.
UPDATE mytable
SET datecolumn = COALESCE(
STR_TO_DATE(stringcolumn, '%m/%d'),
STR_TO_DATE(stringcolumn, '%d/%m/%Y'),
...etc.
);
I can't tell what your different cases are. It might or might not be possible to cover all cases in one pass.
Another alternative is as you say, preprocess the raw data with Perl before you load it into MySQL. But even then, don't fight with regular expressions, use Date::Parse instead.

MySql Not Like Regexp?

I'm trying to find rows where the first character is not a digit. I have this:
SELECT DISTINCT(action) FROM actions
WHERE qkey = 140 AND action NOT REGEXP '^[:digit:]$';
But, I'm not sure how to make sure it checks just the first character...
First there is a slight error in your query. It should be:
NOT REGEXP '^[[:digit:]]'
Note the double square parentheses. You could also rewrite it as the following to avoid also matching the empty string:
REGEXP '^[^[:digit:]]'
Also note that using REGEXP prevents an index from being used and will result in a table scan or index scan. If you want a more efficient query you should try to rewrite the query without using REGEXP if it is possible:
SELECT DISTINCT(action) FROM actions
WHERE qkey = 140 AND action < '0'
UNION ALL
SELECT DISTINCT(action) FROM actions
WHERE qkey = 140 AND action >= ':'
Then add an index on (qkey, action). It's not as pleasant to read, but it should give better performance. If you only have a small number of actions for each qkey then it probably won't give any noticable performance increase so you can stick with the simpler query.
Your current regex will match values consisting of exactly one digit, not the first character only. Just remove the $ from the end of it, that means "end of value". It'll only check the first character unless you tell it to check more.
^[:digit:] will work, that means "start of the value, followed by one digit".