Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does "HAVING" statement with "REPLACE" affects the values?

Tags:

sql

mysql

I have a table with "tag" and "category" columns. The tags may contain spaces, but I want to filter them by a query string that has dashes instead of the spaces (it comes from a URL slug).

I run the following query on mysql:

SELECT GROUP_CONCAT(tag SEPARATOR  ',' ) AS tags
FROM tags 
GROUP BY category 
HAVING REPLACE( tags,  ' ',  '-' ) like "%a%"

The result is:

first-tag,second-tag
third-tag,fourth-tag
fifth-tag

Could someone explain why do the tags that are returned have dashes as well? I would expect (and hope) for the REPLACE to be used for the filtering by the HAVING statement, but the original value to be returned by the query. How would I achieve that?

Here's a fiddle for your reference: http://sqlfiddle.com/#!2/d7573/1

Thank you!

EDIT (by gordon):

For those interested, this problem occurs in this simpler version of the query:

SELECT GROUP_CONCAT(tag) AS tags
FROM tags 
HAVING REPLACE(tags, ' ', '-') is not null;

As @Razvan points out, this is a reference issue. It doesn't happen with the group_concat() directly in the having.

like image 529
Sasha Avatar asked Feb 14 '14 15:02

Sasha


People also ask

What is a replace statement?

The REPLACE statement is used to replace source text. A REPLACE statement can occur anywhere in the source text that a character-string can occur. It must be preceded by a separator period except when it is the first statement in a separately compiled program. It must ends with a separator period.

How the Replace and UPDATE statements differ?

Using MySQL REPLACE statement to update a row This statement is like the UPDATE statement except for the REPLACE keyword. In addition, it has no WHERE clause. Unlike the UPDATE statement, if you don't specify the value for the column in the SET clause, the REPLACE statement will use the default value of that column.

How does replace into work?

REPLACE works exactly like INSERT , except that if an old row in the table has the same value as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted.

How many arguments replace function accepts?

It takes three arguments: the substring to replace, the new string to replace it, and an optional number that indicates how many occurrences to replace. old − This is the old substring to be replaced.


1 Answers

Although it is very intersting, I think you should just fill a bugreport to MySQL. They have a proprietary extensions which modifies the behavior of HAVING.
For example: The SQL standard requires that HAVING must reference only columns in the GROUP BY clause or columns used in aggregate functions. However, MySQL supports an extension to this behavior, and permits HAVING to refer to columns in the SELECT list and columns in outer subqueries as well.

And since your case is not a real scenario (because you don't actually need REPLACE here), I think that this is worth mention, that in case of simple '%%' LIKE patern it does not change the results. Or, if you add OR 1 to HAVING clause, it will also display the correct results.

like image 188
Alexander Avatar answered Oct 08 '22 22:10

Alexander