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
.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With