how to GROUP_CONCAT with Concat - mysql

Product name supplier
A Su1
A Su1
A Su2
B Su1
C Su3
I want like this
A - su1, A-su2, B-su1, C-su3
Query:
SELECT
vtiger_salesorder.salesorder_no,
(Select
group_concat(DISTINCT concat(vtiger_products.productname, '-', vtiger_vendor.vendorname ) SEPARATOR ', ')
FROM
vtiger_salesorder
LEFT Join vtiger_inventoryproductrel ON vtiger_salesorder.salesorderid = vtiger_inventoryproductrel.id
inner Join vtiger_products ON vtiger_products.productid = vtiger_inventoryproductrel.productid
inner Join softMax_SalesOrderVendorInfo ON softMax_SalesOrderVendorInfo.salesorderid = vtiger_salesorder.salesorderid
LEFT JOIN vtiger_vendor ON softMax_SalesOrderVendorInfo.vendorid = vtiger_vendor.vendorid
where (vtiger_salesorder.salesorderid = vtiger_inventoryproductrel.id
AND vtiger_salesorder.salesorderid = vtiger_crmentity.crmid
and (softMax_SalesOrderVendorInfo.status = '0') )Group by vtiger_salesorder.salesorderid Limit 0,1) As SuName1
FROM
vtiger_salesorder
INNER JOIN vtiger_inventoryproductrel ON vtiger_salesorder.salesorderid = vtiger_inventoryproductrel.id
Inner Join vtiger_crmentity ON vtiger_salesorder.salesorderid = vtiger_crmentity.crmid
Order by vtiger_salesorder.salesorder_no

Given your original data, you can simply do this with something like:
select distinct group_concat(ProductName, '-', Supplier separator ', ')
from table t;
I have no idea what the query has to do with the question, because you already seem to have the data in the appropriate format.

Related

Slow MySQL Query When Run As A Procedure

If I run this query directly in PHPMyAdmin, it returns 13420 rows in 0.2091 second, but if I run the exact same query as a stored procedure, it returns the same amount of row but it takes forever and sometimes the SQL server returns an out of memory exception.
I'm at a total loss - any advice would be welcome, because I can't work out why this slows everything down?!
SELECT
el.UID as LUID,
se.UID as DUID,
el.event_title,
el.event_synopsis,
se.behind_the_scenes,
se.sub_event_title,
se.event_eventDateAndTime,
se.event_eventDateAndTimeEnd,
el.event_confirmed,
el.event_active,
(
SELECT GROUP_CONCAT(sp2.color SEPARATOR ',')
FROM setup__spaces sp2
LEFT JOIN events__assigned_spaces eas2 ON ( eas2.space_id = sp2.UID )
LEFT JOIN events__events_list el2 ON (el2.UID = eas2.event_id)
WHERE el2.UID = el.UID
) as spaceColors,
(
SELECT GROUP_CONCAT(sp2.name SEPARATOR ', ')
FROM setup__spaces sp2
LEFT JOIN events__assigned_spaces eas2 ON ( eas2.space_id = sp2.UID )
LEFT JOIN events__events_list el2 ON (el2.UID = eas2.event_id)
WHERE el2.UID = el.UID
) as spaceNames,
(
SELECT GROUP_CONCAT(sp2.UID SEPARATOR ',')
FROM setup__spaces sp2
LEFT JOIN events__assigned_spaces eas2 ON ( eas2.space_id = sp2.UID )
LEFT JOIN events__events_list el2 ON (el2.UID = eas2.event_id)
WHERE el2.UID = el.UID
) as spaceIds,
(
SELECT GROUP_CONCAT(t.UID SEPARATOR ',')
FROM setup__tags t
LEFT JOIN events__assigned_tags eat ON ( eat.tag_id = t.UID )
LEFT JOIN events__events_list el2 ON (el2.UID = eat.event_id)
WHERE el2.UID = el.UID
) as tagIds,
(
SELECT GROUP_CONCAT(t.tag_name SEPARATOR ', ')
FROM setup__tags t
LEFT JOIN events__assigned_tags eat ON ( eat.tag_id = t.UID )
LEFT JOIN events__events_list el2 ON (el2.UID = eat.event_id)
WHERE el2.UID = el.UID
) as tagNames
FROM events__events_list el
INNER JOIN events__sub_events se ON (el.UID = se.event_masterEvent)
WHERE ((el.event_active='1') OR (el.event_active='0' AND el.event_confirmed = '1'))
AND el.company_uid = sp_company_uid
With thanks to #Akina for pointing me in the right direction, I found help from the following places:
stackoverflow.com - Selecting multiple columns/fields in MySQL subquery
geeksengine.com - How to use subquery in JOIN operation in MySQL
Here's the revised code that's now lightning fast!
SELECT
el.UID as LUID,
se.UID as DUID,
el.event_title,
el.event_synopsis,
se.behind_the_scenes,
se.sub_event_title,
se.event_eventDateAndTime,
se.event_eventDateAndTimeEnd,
el.event_confirmed,
el.event_active,
tags.names as tagNames,
tags.ids as tagIds,
spaces.names as spaceNames,
spaces.colors as spaceColors,
spaces.ids as spaceIds
FROM events__events_list el
INNER JOIN events__sub_events se ON (el.UID = se.event_masterEvent)
LEFT JOIN (
SELECT
el3.UID as el2uid,
GROUP_CONCAT(s.name SEPARATOR ', ') as names,
GROUP_CONCAT(s.color SEPARATOR ',') as colors,
GROUP_CONCAT(s.UID SEPARATOR ',') as ids
FROM setup__spaces as s
LEFT JOIN events__assigned_spaces eas ON ( eas.space_id = s.UID )
LEFT JOIN events__events_list el3 ON ( el3.UID = eas.event_id )
GROUP BY el3.UID
) as spaces on spaces.el2uid = el.UID
LEFT JOIN (
SELECT
el2.UID as el2uid,
GROUP_CONCAT(t.tag_name SEPARATOR ', ') as names,
GROUP_CONCAT(t.UID SEPARATOR ',') as ids
FROM setup__tags as t
LEFT JOIN events__assigned_tags eat ON ( eat.tag_id = t.UID )
LEFT JOIN events__events_list el2 ON ( el2.UID = eat.event_id )
GROUP BY el2.UID
) as tags on tags.el2uid = el.UID
WHERE ((el.event_active='1') OR (el.event_active='0' AND el.event_confirmed = '1'))
AND el.company_uid = sp_company_uid

How convert rows to columns(SQL)?

I want to do this:
Desired Output
but I actually have this:
Current Output
this is my sql code:
enter code here
SELECT `a`.`itemId` AS itemId, `a`.`donationId` AS `donationId`,
`a`.`typeId` AS `typeId`, `a`.`currencyId` AS `currencyId`,
`a`.memberId AS memberId, `a`.amount_total AS amount_total, a.ref AS
ref, a.ref_bank AS ref_bank, `a`.`hidden` AS `hidden`, a.code AS code,
concat( `b`.`first_name`, ' ', `b`.`last_name` ) AS member_name,
`c`.currencyCode AS currencyCode, `f`.`name` AS `payment_name`,
e.itemEnvelopId, e.itemId AS itemIdP, e.accountId, e.amount,
e.hidden as envelopHidden, g.NAME, g.new_number
FROM
ai_donation_items `a` LEFT JOIN ai_church_members `b` ON a.memberId = b.memberId
LEFT JOIN ai_currency `c` ON a.currencyId = c.currencyId
LEFT JOIN ai_payment_types `f` ON a.typeId = f.typeId
LEFT JOIN ai_donation_envelops_item as e on a.itemId = e.itemId
LEFT JOIN ai_accounts AS g ON e.accountId = g.accountId
WHERE `a`.`hidden` = 0 AND e.hidden = 0 and a.donationId = 1

Mysql triple join error:Not unique table/alias: 'cushbu_mark_user_favorites'

I have 3 tables in my db
1)cushbu_users (id,first_name,last_name)
2)cushbu_art (id,user_id(FK cushbu_user),title,base_price etc...) -for store user arts
3)cushbu_mark_user_favorites (id,user_id(FK cushbu_user),art_id(FK cushbu_art)) -for marking favourite items
I want to fetch the all art items of a particular user favourited
with count of favourites each art (stored in cushbu_mark_usier_favorites table )
Here is my query
SELECT
cushbu_art.id AS art_id,
cushbu_art.title,
cushbu_art.base_price,
cushbu_art.image_name,
CONCAT(
cushbu_users.first_name,
' ',
cushbu_users.last_name
) AS artist_name,COUNT(cushbu_mark_user_favorites.art_id)
FROM
cushbu_art
JOIN cushbu_mark_user_favorites ON cushbu_mark_user_favorites.art_id = cushbu_art.id
JOIN cushbu_users ON cushbu_users.id = cushbu_art.artist_id
LEFT JOIN cushbu_mark_user_favorites ON cushbu_art.id=cushbu_mark_user_favorites.art_id
WHERE
cushbu_mark_user_favorites.user_id = 68
But i got Not unique table/alias: 'cushbu_mark_user_favorites' this join statement
LEFT JOIN cushbu_mark_user_favorites ON cushbu_art.id=cushbu_mark_user_favorites.art_id
UPDATE
SELECT
a.id AS art_id,
a.title,
a.base_price,
a.image_name,
CONCAT(
c.first_name,
' ',
c.last_name
) AS artist_name,COUNT(b.art_id)
FROM
cushbu_art a
JOIN cushbu_mark_user_favorites b ON b.art_id = a.id
JOIN cushbu_users c ON c.id = a.artist_id
LEFT JOIN b ON a.id=b.art_id
WHERE
b.user_id = 68
Try below query.
SELECT
cushbu_art.id AS art_id,
cushbu_art.title,
cushbu_art.image_name,
CONCAT(
cushbu_users.first_name,
' ',
cushbu_users.last_name
) AS artist_name , b.favorites_count as total_fav
FROM
cushbu_mark_user_favorites
LEFT JOIN cushbu_art ON cushbu_art.id=cushbu_mark_user_favorites.art_id
LEFT JOIN cushbu_users ON cushbu_users.id = cushbu_art.artist_id
LEFT JOIN (SELECT art_id,count(*) as favorites_count FROM cushbu_mark_user_favorites GROUP BY art_id) as b ON b.art_id=cushbu_art.id
WHERE cushbu_mark_user_favorites.user_id=1
GROUP BY cushbu_art.id
Hope this will helpful to you.

How do I return a single row as well as multple entries using group_concat in MySQL

I hope this one is a relatively easy one to solve, but here is the problem I'm faced with:
SQL Query:
SELECT
job.job_id
,job_reference
,job_title
,jc.name as job_category_name
,ps.name as position_status_name
,group_concat(pt.name ORDER BY pt.position_type_id SEPARATOR ' / ') as position_type_name
,cty.name as city_name
,min.amount as min_salary
,max.amount as max_salary
,job_description
,skills_required
,additional_notes
FROM job
INNER JOIN job_category jc ON job.job_category_id = jc.job_category_id
INNER JOIN position_status ps ON job.position_status_id = ps.position_status_id
INNER JOIN job_position_type jpt ON job.job_id = jpt.job_id
INNER JOIN position_type pt ON jpt.position_type_id = pt.position_type_id
INNER JOIN city cty ON job.city_id = cty.city_id
INNER JOIN salary min ON job.min_salary_id = min.salary_id
INNER JOIN salary max ON job.max_salary_id = max.salary_id;
The query is only returning the entries where job_position_type table has multiple entries and not if job_position_type only has a single entry.
Cheers,
Tim
OK so I managed to sort out my problem pretty easily actually, here is my original SQL as specified above:
SELECT
job.job_id
,job_reference
,job_title
,jc.name as job_category_name
,ps.name as position_status_name
,group_concat(pt.name ORDER BY pt.position_type_id SEPARATOR ' / ') as position_type_name
,cty.name as city_name
,min.amount as min_salary
,max.amount as max_salary
,job_description
,skills_required
,additional_notes
FROM job
INNER JOIN job_category jc ON job.job_category_id = jc.job_category_id
INNER JOIN position_status ps ON job.position_status_id = ps.position_status_id
INNER JOIN job_position_type jpt ON job.job_id = jpt.job_id
INNER JOIN position_type pt ON jpt.position_type_id = pt.position_type_id
INNER JOIN city cty ON job.city_id = cty.city_id
INNER JOIN salary min ON job.min_salary_id = min.salary_id
INNER JOIN salary max ON job.max_salary_id = max.salary_id;
And this is what the query returns:
And the solution was just to add a group by clause so that it seperates the rows, here is my update SQL:
SELECT
job.job_id
,job_reference
,job_title
,jc.name as job_category_name
,ps.name as position_status_name
,group_concat(pt.name ORDER BY pt.position_type_id SEPARATOR ' / ') as position_type_name
,cty.name as city_name
,min.amount as min_salary
,max.amount as max_salary
,job_description
,skills_required
,additional_notes
FROM job
INNER JOIN job_category jc ON job.job_category_id = jc.job_category_id
INNER JOIN position_status ps ON job.position_status_id = ps.position_status_id
INNER JOIN job_position_type jpt ON job.job_id = jpt.job_id
INNER JOIN position_type pt ON jpt.position_type_id = pt.position_type_id
INNER JOIN city cty ON job.city_id = cty.city_id
INNER JOIN salary min ON job.min_salary_id = min.salary_id
INNER JOIN salary max ON job.max_salary_id = max.salary_id
GROUP BY pt.position_type_id;
And here is the expected result I wanted:
Thanks once again to #Adrien Brunelat for taking a look at my question.

Mysql return more than one row

I have this query.
SELECT notes.id,enter.name as 'enter_name',step.title as 'flow status',notes.user_name as user_created,notes.created,notes.rel_client_id,td_doc_nr.value_string as 'document number',enter.enter_code,
IF(!ISNULL(td_doc_nr.value_string),
(SELECT GROUP_CONCAT(product_name SEPARATOR ',') from notes d
join note_bundles b on b.note_id = d.id
join note_products p on p.doc_bundle_id = b.id
join note_product_get_fields f on f.doc_product_id = p.id
join note_product_get_field_data fd on fd.get_field_id = f.id
where d.doc_nr = td_doc_nr.value_string
and value_string ='auto')
,NULL) as test
FROM notes notes
JOIN notes_steps step ON step.id = notes.step_id
JOIN notes_enters enter ON enter.id = notes.enter_id
LEFT JOIN notes_custom_fields tf_doc_nr ON tf_doc_nr.name = 'note_number' AND tf_doc_nr.rel_entity_id = enter.id
LEFT JOIN notes_custom_field_data td_doc_nr ON td_doc_nr.rel_entity_id = notes.id AND
td_doc_nr.field_instance_id = tf_doc_nr.id
WHERE notes.enter_id in (777) AND notes.status = 1
I added this subquery to the 'if statement'
SELECT GROUP_CONCAT(product_name SEPARATOR ',') from nontes d
join note_bundles b on b.note_id = d.id
join note_products p on p.doc_bundle_id = b.id
join note_product_get_fields f on f.doc_product_id = p.id
join note_product_get_field_data fd on fd.get_field_id = f.id
where d.doc_nr = 'G7777777'
and value_string ='auto'
After this I added a new column.
SELECT GROUP_CONCAT(product_name SEPARATOR ','),GROUP_CONCAT(DISTINCT b.msisdn SEPARATOR ',') from notes d
join note_bundles b on b.note_id = d.id
join note_products p on p.doc_bundle_id = b.id
join note_product_get_fields f on f.doc_product_id = p.id
join note_product_get_field_data fd on fd.get_field_id = f.id
where d.doc_nr = 'G7777777'
and value_string ='auto'
It returns two columns.
How can I return two columns?Is it possible? :) Thanks
A subquery inside an IF statement can't return multiple columns. You will need to join the subquery into the results, and pull out the two separate columns individually:
SELECT ...
IF(!ISNULL(td_doc_nr.value_string), sub.one, NULL) as one,
IF(!ISNULL(td_doc_nr.value_string), sub.two, NULL) as two
FROM ...
LEFT JOIN (
SELECT d.doc_nr, GROUP_CONCAT(product_name SEPARATOR ','),GROUP_CONCAT(DISTINCT b.msisdn SEPARATOR ',') from documents d
join document_bundles b on b.document_id = d.id
join document_products p on p.doc_bundle_id = b.id
join document_product_cstm_fields f on f.doc_product_id = p.id
join document_product_cstm_field_data fd on fd.cstm_field_id = f.id
where value_string ='auto'
group by d.doc_nr
) sub on sub.doc_nr = td_doc_nr.value_string
A correlated subquery inside an IF statement can only return 1 column and 1 row, this is why you are getting the error. However, looking over your query the only outer reference inside the subquery is
d.doc_nr = td_doc_nr.value_string
So you do not need actually need a correlated subquery and you can achieve the same result by moving the subquery to a join and grouping by doc_nr within the subquery, which will probably be much more efficient, and it will allow you to return the 2 columns you want:
SELECT tickets.id,
source.name as 'source_name',
flow_stage.title as 'flow status',
tickets.user_name as user_created,
tickets.created,
tickets.rel_client_id,
td_doc_nr.value_string as 'document number',
source.source_code,
IF(!ISNULL(td_doc_nr.value_string), ProductNames, NULL) as test,
d.MSISDNS
FROM tickets tickets
JOIN tickets_flow_stages flow_stage
ON flow_stage.id = tickets.flow_stage_id
JOIN tickets_sources source
ON source.id = tickets.source_id
LEFT JOIN tickets_custom_fields tf_doc_nr
ON tf_doc_nr.name = 'document_number'
AND tf_doc_nr.rel_entity_id = source.id
LEFT JOIN tickets_custom_field_data td_doc_nr
ON td_doc_nr.rel_entity_id = tickets.id
AND td_doc_nr.field_instance_id = tf_doc_nr.id
LEFT JOIN
( SELECT d.Doc_nr,
GROUP_CONCAT(product_name SEPARATOR ',') AS ProductNames,
GROUP_CONCAT(DISTINCT b.msisdn SEPARATOR ',') AS MSISDNS
from documents d
INNER JOIN document_bundles b
ON b.document_id = d.id
INNER JOIN document_products p
ON p.doc_bundle_id = b.id
INNER JOIN document_product_cstm_fields f
ON f.doc_product_id = p.id
INNER JOIN document_product_cstm_field_data fd
ON fd.cstm_field_id = f.id
WHERE value_string ='auto'
GROUP BY d.Doc_nr
) d
ON d.doc_nr = td_doc_nr.value_string
WHERE tickets.source_id IN (114,122,125,129,131)
AND tickets.status = 1