MySQL group by issue on text field (Field contain HTML) - mysql

I have a template table. A single template can have multiple HTML pages that stored in template_pages table.
A complete template is combination of multiple pages.
My requirement is to check duplicate templates. For that I have to match concatenate pages and match to check duplicates. I have build following query for that
Select Count(id) as count, GROUP_CONCAT(id SEPARATOR ', ') as duplicate_templates from
(select template_id as id, GROUP_CONCAT(TRIM(template_pages.template) SEPARATOR ', ') as full_template from template_pages
left join templates on templates.id = template_pages.template_id
where template_pages.template != ""
and templates.deleted_at IS NOT NULL
group by template_id
) as templates
group by full_template having count(full_template) >1;
But this query not giving exact results. Its matching some unmatched records. Some template have some similar data but not exactly same also coming in duplicates.

#ajay, seems you have issue at Where cluse with DELETE_AT column. Please verify that.
It's working for me.

Related

Mysql show other different cell data with under group by same name

Let's assume I have a table which store register user data, the records might have same registered name but different email, like following:
I want to create a front view to manipulate those data but I don't want those same name show repeatedly, can mysql statement query to output result like
this is the result so far I can do but it can't bind same name into one.
select * from `register`
where `fullname` in (
select `fullname` from `register`
group by `fullname` having count(*) > 1
)
One thing you could do is to do a SELECT DISTINCT on the duplicate row, and make use of the GROUP_CONCAT(); function in MYSQL to concatenate your desired values into one row, and GROUP BY fullname to get the order you wanted.
Note that I am also putting the user ids into a grouped row, so that you can track which ids belong to which name.
SELECT
DISTINCT fullname as full_name,
GROUP_CONCAT(id SEPARATOR ', ') as user_ids,
GROUP_CONCAT(email SEPARATOR ', ') as emails
FROM
tbl_register
GROUP BY
tbl_register.fullname
Working SQL Fiddle
This would be the logical way to do it. Hope this helped. :)
More information on the GROUP_CONCAT(); function here: https://dev.mysql.com/doc/refman/8.0/en/group-by-functions.html#function_group-concat
Try this:
SELECT DISTINCT *duplicate_column* FROM *table_name1* WHERE *col_id* IN (SELECT *cols_to_dusplay* FROM *table_name1* GROUP_BY *duplicate_column*

Update Group_Concat from multiple rows

I am trying to update 1 column with the results of concatenating several rows.
I am able to do it in a Select query but can't figure it out in an Update query.
SELECT GROUP_CONCAT(SizeTemp SEPARATOR ', ') FROM Table GROUP BY ParentSKU
Also, the result separates everything with a coma which is fine but I need the last string NOT to be followed by a coma. In the example below: no coma after XL
S,M,L,XL
Thanks for any help.
You can use update with inner query as shown below:
UPDATE TABLE AS t1,
(SELECT ParentSKU, GROUP_CONCAT(SizeTemp SEPARATOR ', ') AS sizes FROM TABLE GROUP BY ParentSKU) AS t2
SET t1.sizes = t2.sizes
WHERE t1.ParentSKU = t2.ParentSKU
AND t1.ParentSKU = ?
Criteria/column may differ based on which column needs updating.

Using distinct and order by in subquery

I am trying to get distinct 'productnumber' ordered by the 'createdate' but at the end I need only "productnumber" sorted by 'createdate' (I cannot use top as the 'productnumber' varies in a wide flexible range).
The distinct product number is needed to be concatenated with comma (,) for e.g.
123,245,787,875 (each number represents a productnumber)
The required query looks like somewhat (this query doesn't work and gives an error The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified):
SELECT stuff(
(
SELECT distinct ',' + productnumber
FROM Product
ORDER BY createdate
FOR XML path('')
)), 1, 1, '')
Could anyone help in how to go about to get the desired result.
As Mikael Eriksson suggested, using Group By clause solved the problem. Thanks Mikael
SELECT stuff((SELECT ',' + productnumber
FROM product a
ORDER BY a.createdate FOR xml path('')),1,1,'')
AS destn_str

MySQL - Using Order By result created by a subquery group_concat or join issue

This is a query I've been puzzling over for quite some time, I've never been able to get it to work quite right and after about 40 hours of pondering I've gotten to this point.
Setup
For the example issue we have 2 tables, one being...
field_site_id field_sitename field_admins
1 Some Site 1,
2 Other Site 1,2,
And the other is admins like...
field_user_id field_firstname field_lastname
1 Joe Bloggs
2 Barry Wills
Now all this query is designed to do is the following:
List all sites in the database
Using a JOIN and FIND_IN_SET to pull each admin
And GROUP_CONCAT(field_firstname, ' ', field_lastname) with a GROUP BY to build a field with the real user names.
Also allow HAVING to filter on the custom result to narrow the results down further.
All this part works perfectly fine.
What I can't work out how to achieve is to sort the results by the GROUP_CONCAT result, I imagine this is being the ORDER BY works before the concat function therefore the data doesn't exist to order by it, so what would the alternative be?
Code examples:
SELECT *
GROUP_CONCAT(DISTINCT field_firstname, ' ', field_lastname ORDER BY field_lastname SEPARATOR ', ') AS field_admins_fullname,
FROM `table_sites`
LEFT JOIN `table_admins` ON FIND_IN_SET( `table_admins`.`field_user_id`, `table_sites`.`field_site_id` ) > 0
GROUP BY field_site_id
I also tried a query that used a subquery to gather the group_concat result as below...
( SELECT GROUP_CONCAT(field_firstname, ' ', field_lastname ORDER BY field_lastname ASC SEPARATOR ', ') FROM table_admins
WHERE FIND_IN_SET( `table_admins`.`field_user_id`, `table_sites`.`field_admins` ) > 0
) AS field_admins_fullname
Conclusion
Either way attempting to ORDER BY field_admins_fullname will not create the correct results, it won't error out but assume that's because the given ORDER BY is blank so it just does whatever it wants.
Any suggestions would be welcome, if this is just not possible, what would be another recommend index methodology?
Two things I see wrong:
1st, is the JOIN. It should be using s.field_admins and not field_site_id :
ON FIND_IN_SET( a.field_user_id, s.field_admins ) > 0
2nd, you should use the CONCAT() function (to conactenate fields from the same row) inside the GROUP_CONCAT().
Try this:
SELECT s.field_site_id
, s.field_sitename
, GROUP_CONCAT( CONCAT(a.field_firstname, ' ', a.field_lastname)
ORDER BY a.field_lastname ASC
SEPARATOR ', '
)
AS field_admins_fullname
FROM table_sites s
LEFT JOIN table_admins a
ON FIND_IN_SET( a.field_user_id, s.field_admins ) > 0
GROUP BY s.field_site_id
Friendly advice:
Don't use Do use
------------ --------
table_sites site
table_admins admin
field_site_id site_id
field_sitename sitename
field_admins admins
But what should really be stressed, is your setup. Having fields that have comma separated values lead to this kind of horrible queries that use FIND_IN_SET() for joins and GROUP_CONCAT() for showing results. Horrible to see, difficult to maintain and most important, very, very slow as no index can be used.
You should have something like this instead:
Setup suggestion
Table: site
site_id sitename
1 Some Site
2 Other Site
Table: site_admin
site_id admin_id
1 1
2 1
2 2
Table: admin
user_id firstname lastname
1 Joe Bloggs
2 Barry Wills
I think you need to repeat the complex CONCAT statement you are selecting within the ORDER BY.
So your order by would be more like...
ORDER BY (GROUP_CONCAT(DISTINCT field_firstname, ' ',
field_lastname ORDER BY field_lastname SEPARATOR ', ')) ASC
I have not tried this but I had a similar issue which this seemed to solve but it was much simpler without the DISTINCT etc.
wrong group by, try this ?
GROUP BY field_site_id

MySQL returning an empty field: CONCAT(nonEmpty1,empty2,nonEmpty3) = NULL

I have PHP 5 code accessing a MyISAM table on MySQL 5 server. The query looks like this:
SELECT CONCAT(fName1,' ',mName2,' ',lName3) AS userName
FROM users
WHERE level > 10
When there's no mName filled in, I am expecting output like "fname lname" , but I'm getting "" (empty string) instead (the number of rows returned is correct). Where am I making a mistake?
PHP code:
<?php
$result = mysql_query($the_above_query);
while ($result_row = mysql_fetch_assoc($result)) {
// do stuff with the name
// except I'm getting empty strings in $result_row['userName']
}
Relevant part of table structure:
CREATE TABLE users {
/* -snip- */
`fName1` varchar(50) default NULL,
`mName2` varchar(50) default NULL,
`lName3` varchar(50) default NULL,
`level` int(11) default 0,
/* -snip- */
} ENGINE=MyISAM DEFAULT CHARSET=utf8;
(also, is this way (column concatenation in MySQL) a good idea, or should I fetch the columns to PHP and join them there?)
Turns out that I was getting back a NULL; PHP treats a returned NULL and empty string("") similarly, you'd have to compare with === to see the difference.
From google: http://bugs.mysql.com/bug.php?id=480
[23 May 2003 4:32] Alexander Keremidarski
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.mysql.com/documentation/ and the instructions on
how to report a bug at http://bugs.mysql.com/how-to-report.php
This is doccumented behaviour of CONCAT() function.
From Manual chapter 6.3.2 String Functions
CONCAT(str1,str2,...)
Returns the string that results from concatenating the arguments. Returns NULL if any
argument is NULL
Use CONCAT_WS() instead or wrap NULLable paremeters with IFNULL() function.
Documentation and usage for CONCAT_WS: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_concat-ws
From MYSQL docs
CONCAT() returns NULL if any argument
is NULL.
you want to use CONCAT_WS()
CONCAT_WS(separator,str1,str2,...)
But best bet is to just pull it back and use php cause if you need a different format or just one of those fields later you'll have to make another db call
In MySQL concatenating any string to a NULL value results in NULL.
You have to check for NULL before concatenate using IFNULL:
SELECT CONCAT(IFNULL(fName1,''),' ',IFNULL(mName2,''),' ',IFNULL(lName3,'')) AS userName
FROM users
WHERE level > 10
This was the solution I came up with which included Keeper and Ersatz answer. System would not allow me to vote you guys up though :(
CONCAT_WS(IFNULL(ts_usr_nameDetails.first_name,''),' ',IFNULL(ts_usr_lib_connectionNameDetails.first_name,'')) AS composerName
This allowed for some amazing results
This is an answer based on the solution above by #chocojosh and another question here: MySQL/SQL: Update with correlated subquery from the updated table itself
I had a similar problem, but I was trying to concat a bunch of group_concats and some were NULL which caused the whole row to be NULL. The goal was to place data from other tables into a single field in the main table to allow fulltext searches.
Here is the SQL that worked. Note the first parameter for concat_ws I made ' ', this allowed for spaces between the values for the fulltext field.
Hope this helps someone.
update
products target
INNER JOIN
(
select p.id,
CONCAT_WS(
' ',
(select GROUP_CONCAT(field SEPARATOR ' ') from table1 where productId = p.id),
p.title,' ',
(select GROUP_CONCAT(field, ' ', descriptions SEPARATOR ' ') from table2 where productId = p.id),
(select GROUP_CONCAT(field SEPARATOR ' ') from table3 where productId = p.id),
(select GROUP_CONCAT(field, ' ', catno SEPARATOR ' ') from table4 where productId = p.id),
(select GROUP_CONCAT(field SEPARATOR ' ') from table5 where productId = p.id),
(select GROUP_CONCAT(field SEPARATOR ' ') from table6 where productId = p.id),
(select GROUP_CONCAT(field SEPARATOR ' ') from table7 where productId = p.id)
) as ft
from products p
) as source
on target.id = source.id
set target.fulltextsearch = source.ft
you could also the COALESCE() function to return the first non-null value. Like so:
SELECT CONCAT(fName1,COALESCE(CONCAT(' ',mName2,' '),' '),lName3) AS userName
FROM users
WHERE level > 10
This would also only put one space if there was no middle name and a space before and after if there was a middle name.
Reference for this function can be found at: http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_coalesce