mysql group_concat comma separated ids to match names - mysql

I wrote this query to find the list of shops selling what categories.
SELECT GROUP_CONCAT(distinct(sub_category_id)) AS s,
vendor_id AS v
FROM link_products_lists_vendors
GROUP BY vendor_id;
This results in,
+---------------------------------------+------------+
| category_ids | vendor_ids |
+---------------------------------------+------------+
| 24,28,25,16,26,23,27,2 | 3 |
| 2 | 67 |
| 19,28,17,16,20,2 | 68 |
| 19,28,24,26,23,21,16,27,22,17,25,2 | 122 |
| 16,2 | 123 |
| 28,17,22,21,18,16,26,27,20,23,25,2 | 124 |
| 22,19,21,20,16,24,28,25,23,26,2 | 125 |
| 23,24,26,25,28,16,20,27,19,2 | 126 |
| 19,26,28,18,20,27,22,16 | 127 |
| 22,26,28,21,23,20,24,19,16,17,27,25,2 | 128 |
| 2 | 129 |
| 2 | 133 |
| 19,20,28,16,27,25,21,23,26,24,22 | 135 |
| 23,28,17,22,26,21,16,20,27,24,25,2 | 136 |
| 19,17,16,21,23,26,22,25,27,20,28 | 137 |
| 19,20,26,22,21,24,23,17,28,16,27,25,2 | 138 |
| 19,20,23,28,26,21,24,16,27,22,25,17,2 | 139 |
| 22,27,20,21,24,17,23,28,26,19,25,2 | 142 |
| 19,28,17,20,2 | 143 |
+---------------------------------------+------------+
19 rows in set (0.01 sec)
What I want now is something like,
+-------------------------- -----------+--- ----------+
| category_names | vendor_names |
+---------------------------------------+--------------+
| mobiles,laptops,desktops | abcShop |
| mobiles | xyzShop |
| desktops,mouses,keyboards | pqrShop |
+---------------------------------------+--------------+
I have the categories table as,
+----+---------------+
| id | name |
+----+---------------+
| 17 | desktops |
| 18 | external_hdds |
| 26 | headphones |
| 27 | headsets |
| 22 | keyboards |
| 16 | laptops |
| 24 | memory_cards |
| 2 | mobile-phones |
| 21 | mouses |
| 25 | pendrives |
| 19 | printers |
| 20 | routers |
| 23 | speakers |
| 28 | tablets |
+----+---------------+
Vendors table as,
+-----+----------------------+
| id | name |
+-----+----------------------+
| 108 | abcShop |
| 109 | xyzShop |
| 45 | pqrShop |
| 89 | . |
| 63 | . |
| 64 | . |
+-----+----------------------+
How should I write a query that will not display ids but use the table that displays ids and displays names? I have no clue from where to start this. Please help!

Just join in the other tables and select those values instead
SELECT GROUP_CONCAT(distinct(c.name)) AS s,
v.name AS v
FROM link_products_lists_vendors l
JOIN categories c on l.category_id = c.id
JOIN vendors v on l.vendor_id = v.id
GROUP BY v.name;
This works as long as vendor names and description names are unique.

Related

Make a SQL query on three tables with a NOT-LIKE clause

I need to extract all servers that are not member of a specified group.
I have 3 tables: host (containing hosts), hostgroup_relation (containing the host id and the hostgroup id), hostgroup (containing hostgroups)
I can get the relationships, but I need every hosts that are NOT member of the group with id 180
Host:
SELECT host_id,host_name FROM host LIMIT 10;
+---------+-------------------+
| host_id | host_name |
+---------+-------------------+
| 1482 | AADSYNC1 |
| 442 | Acces-Point-Wifi |
| 1916 | ADAUDIT1 |
| 1562 | ADMORA1 |
| 2247 | ADMRDS2 |
| 2226 | ADSECU1 |
| 1203 | ADSELFSERVICE1 |
| 1172 | ALFRESCO1 |
| 1841 | ALFRESCO2 |
| 172 | Antispam-Ironport |
+---------+-------------------+
Hostgroups:
SELECT hg_id, hg_name FROM hostgroup LIMIT 10
+-------+----------------------+
| hg_id | hg_name |
+-------+----------------------+
| 82 | Antivirus-Trend |
| 65 | Autocoms |
| 72 | Baies-de-stockage |
| 78 | Consoles |
| 192 | Databases-All |
| 193 | Databases-Main |
| 68 | Databases-MySql |
| 67 | Databases-Oracle |
| 181 | Databases-PostgreSql |
| 69 | Databases-SQLServer |
+-------+----------------------+
Host/hostgroup relation:
SELECT * FROM hostgroup_relation LIMIT 10;
+--------+-----------------+--------------+
| hgr_id | hostgroup_hg_id | host_host_id |
+--------+-----------------+--------------+
| 5698 | 70 | 1167 |
| 6772 | 53 | 1167 |
| 6820 | 144 | 1369 |
| 6821 | 62 | 1369 |
| 6822 | 53 | 1369 |
| 6823 | 70 | 1369 |
| 6825 | 62 | 1370 |
| 6826 | 53 | 1370 |
| 6827 | 70 | 1370 |
| 6829 | 62 | 1371 |
+--------+-----------------+--------------+
Here is where I've gone so far:
SELECT host.host_name, hostgroup.hg_name
FROM host, hostgroup_relation, hostgroup
WHERE hostgroup_relation.hostgroup_hg_id = hostgroup.hg_id
AND hostgroup_relation.host_host_id = host.host_id
LIMIT 10;
+-----------+-----------------------------+
| host_name | hg_name |
+-----------+-----------------------------+
| AADSYNC1 | Default-bi |
| AADSYNC1 | Serveurs-Virtuels |
| AADSYNC1 | Serveurs-Windows |
| AADSYNC1 | Reboot_serveurs-12h00:14h00 |
| ADAUDIT1 | Default-bi |
| ADAUDIT1 | Serveurs-Virtuels |
| ADAUDIT1 | Serveurs-Windows |
| ADAUDIT1 | Reboot_serveurs-12h00:14h00 |
| ADMORA1 | Default-bi |
| ADMORA1 | Reboot_serveurs-00h00:4h00 |
+-----------+-----------------------------+
And I need a list of all servers that are not in a specified group.
You need to do a simple join.
This could work:
SELECT h.host_id, h.host_name
FROM host h
LEFT OUTER JOIN hostgroup_relation hgr ON (hgr.host_host_id = h.host_id AND hgr.hostgroup_hg_id = 180)
WHERE hgr.hgr_id IS NULL
Try this:
select h.host_id, hg.host_name, hg.hg_id
from host h
join hostgroup_relation hg
where h.host_id = hg.host_host_id
and hg_id not in 180;

convert rows into coumns dinamiacally for some table with CONCAT and GROUP_CONCAT mysql query

by followed Mysql query to dynamically convert rows to columns on the basis of two columns,
I have 4 table to convert dinamiacally rows into columns as RESULT
TABLE A
| id | stages |
-----+----------
| 1 | Stage A |
| 2 | Stage B |
| 3 | Stage C |
TABLE B
| id_b | code | lessons |
-------+------+--------------
| 10 | FIS | Physics |
| 11 | MAT | Mathematics |
| 12 | KIM | Chemistry |
| 13 | BIO | Biology |
TABLE C
|id_c| students |
-----+-------------
| 20 | student 20 |
| 21 | student 21 |
| 22 | student 22 |
| 23 | student 23 |
| 24 | student 24 |
| 25 | student 25 |
| 26 | student 26 |
| 27 | student 27 |
TABLE D
| id_d | id_a | id_b | id_c | value_m | value_n |
-------+------+------+------+---------+----------
| 201 | 1 | 11 | 20 | 71 | 73 |
| 203 | 1 | 13 | 20 | 80 | 87 |
| 204 | 2 | 10 | 21 | 72 | 75 |
| 206 | 2 | 13 | 21 | 76 | 78 |
| 208 | 2 | 12 | 22 | 72 | 78 |
| 209 | 2 | 13 | 22 | 76 | 80 |
| 210 | 3 | 11 | 23 | 73 | 71 |
| 211 | 3 | 12 | 23 | 71 | 77 |
| 212 | 3 | 13 | 23 | 78 | 81 |
| 213 | 3 | 10 | 24 | 70 | 81 |
| 214 | 3 | 11 | 25 | 71 | 82 |
| 215 | 3 | 12 | 26 | 74 | 83 |
| 215 | 3 | 13 | 27 | 78 | 80 |
RESULT
| students | FIS_1 | MAT_1 | KIM_1 | BIO_1 | FIS_2 | MAT_2 | KIM_2 | BIO_2 | FIS_3 | MAT_3 | KIM_3 | BIO_3 |
-------------+-------+-------+-------+-------+--------+------+-------+-------+-------+-------+-------+--------
| student 20 | | 71,73 | | 80,87 | | | | | | | | |
| student 21 | | | | | 72,75 | 76,78 | | | | | | |
| student 22 | | | | | | | 72,78 | 76,80 | | | | |
| student 23 | | | | | | | | | | 73,71 | 71,77 | 78,81 |
| student 24 | | | | | | | | | 70,81 | | | |
| student 25 | | | | | | | | | | 71,82 | | |
| student 26 | | | | | | | | | | | 74,83 | |
| student 27 | | | | | | | | | | | | 78,80 |
Where FIS_1, MAT_1,... FIS_2, MAT_2.., FIS_3, MAT_3.. is CONCAT from TABLE B kode and TABLE A id,
and value MAT_1, BIO_1... is CONCAT from TABLE D value_m and value_n
It's Posible? How can I do that with GROUP_CONCAT mysql query? I've tried it but still not successful..
Thanks for your advance..

Multiple table join with possible conditional matches

I have several tables that I combine in an application I'm creating in PHP that essentially creates a check list. I realize I could solve this problem using a conditional in PHP, but am curious if MySQL is capable of accomplishing this and if so, how? Specifically, I have four tables which are queried using the following statement:
SELECT
cl_status.status,
users.user_first,
cl_status.date AS status_date,
cl_status.id AS status_id,
cl_status.criteria_id,
cl_criteria.id AS cid,
cl_criteria.description AS description
FROM cl_criteria
LEFT JOIN cl_lists
ON cl_criteria.cl_id = cl_lists.id
RIGHT JOIN cl_status
ON cl_criteria.id = cl_status.criteria_id
LEFT JOIN users
ON cl_status.user_id = users.user_id
WHERE cl_lists.id = '1'
Table one - cl_lists:
+----+------------------+------------+------------+-------+
| id | title | date | comp_level | owner |
+----+------------------+------------+------------+-------+
| 1 | Newcomer's guide | 1452473606 | 1 | 1 |
+----+------------------+------------+------------+-------+
Table two - cl_assign:
+----+-------+-------+------------+
| id | cl_id | owner | date |
+----+-------+-------+------------+
| 1 | 1 | 1 | 1455843514 |
+----+-------+-------+------------+
Table three - cl_status:
+----+-------------+---------+-------------+------------+--------+----------+
| id | criteria_id | user_id | description | date | status | comments |
+----+-------------+---------+-------------+------------+--------+----------+
| 2 | 66 | 1 | | NULL | 1 | NULL |
| 15 | 65 | 1 | | 1455842197 | 5 | NULL |
| 16 | 67 | 1 | | 1455842201 | 5 | NULL |
| 17 | 68 | 1 | | 1455842203 | 5 | NULL |
| 18 | 69 | 1 | | 1455842217 | 0 | NULL |
| 19 | 70 | 1 | | 1455842222 | 5 | NULL |
| 20 | 72 | 1 | | 1455842237 | 1 | NULL |
| 21 | 71 | 1 | | 1455842234 | 0 | NULL |
| 22 | 73 | 1 | | 1455842246 | 5 | NULL |
| 23 | 76 | 1 | | 1455842249 | 5 | NULL |
| 24 | 77 | 1 | | 1455842268 | 5 | NULL |
| 25 | 78 | 152 | | 1455854420 | 3 | NULL |
| 26 | 81 | 1 | | 1455843660 | 5 | NULL |
+----+-------------+---------+-------------+------------+--------+----------+
Table four - users:
+---------+------------+
| user_id | user_first |
+---------+------------+
| 1 | Mark |
| 2 | Test |
+---------+------------+
Ideally, I'd like the join to look like this:
+--------+------------+-------------+-----------+-------------+------+-----------------------------+
| status | user_first | status_date | status_id | criteria_id | cid | description |
+--------+------------+-------------+-----------+-------------+------+-----------------------------+
| 5 | Mark | 1455842197 | 15 | 65 | 65 | Tour of facility |
| 5 | Mark | 1455842201 | 16 | 67 | 67 | Tax forms |
| 5 | Mark | 1455842203 | 17 | 68 | 68 | 2 forms of ID |
| 0 | Mark | 1455842217 | 18 | 69 | 69 | Benefits | |
| 5 | Mark | 1455842246 | 22 | 73 | 73 | Intro to policies |
| 5 | Mark | 1455842249 | 23 | 76 | 76 | Setup email account |
| NULL | NULL | NULL | NULL | 78 | 78 | Setup Computer account |
+--------+------------+-------------+-----------+-------------+------+-----------------------------+
However, it looks like this:
+--------+------------+-------------+-----------+-------------+------+-----------------------------+
| status | user_first | status_date | status_id | criteria_id | cid | description |
+--------+------------+-------------+-----------+-------------+------+-----------------------------+
| 5 | Mark | 1455842197 | 15 | 65 | 65 | Tour of facility |
| 5 | Mark | 1455842201 | 16 | 67 | 67 | Tax forms |
| 5 | Mark | 1455842203 | 17 | 68 | 68 | 2 forms of ID |
| 0 | Mark | 1455842217 | 18 | 69 | 69 | Benefits |
| 5 | Mark | 1455842246 | 22 | 73 | 73 | Intro to policies |
| 5 | Mark | 1455842249 | 23 | 76 | 76 | Setup email account |
| 3 | Temp | 1455854420 | 25 | 78 | 78 | Setup Computer account |
+--------+------------+-------------+-----------+-------------+------+-----------------------------+
Is there a way to apply the conditional before the join? Or another way to accomplish the result set that I want?
EDIT
This is a screenshot of what the application looks like:
The criteria table will include steps of every checklist I have. The list table is a list of the various checklists. The status table allows every user (such as Mark, or Test) to look at the same checklist and complete it as if it was a separate document. It also populates the date/time that the item was updated by that user.
I suspect that the RIGHT JOIN you have in your query is causing the records you want to appear to be filtered out. Remember that t1 RIGHT JOIN t2 is the same as t2 LEFT JOIN t1, meaning that t1 will lose any record which does not appear in t2, with t2 keeping all its records. Try this:
SELECT cl_status.status, users.user_first, cl_status.date AS status_date,
cl_status.id AS status_id, cl_status.criteria_id, cl_criteria.id AS cid,
cl_criteria.description AS description
FROM cl_criteria LEFT JOIN cl_lists
ON cl_criteria.cl_id = cl_lists.id
LEFT JOIN cl_status
ON cl_criteria.id = cl_status.criteria_id
LEFT JOIN users
ON cl_status.user_id = users.user_id
WHERE cl_lists.id = '1'

Issue while joining many tables

I have four tables :
products sizes
----------------------------- -----------------------------------
| product_id | product_name | | pizza_size_id | pizza_size_name |
----------------------------- -----------------------------------
| 39 | Italyan | | 1 | Small |
| 40 | Classic | | 2 | Medium |
| 41 | Lamb | | 3 | Large |
| 42 | Evi | -----------------------------------
-----------------------------
menu_details
--------------------------------------------------------
| id | order_details_fk | pizza_menus_fk | products_fk |
--------------------------------------------------------
| 17 | 132 | 92 | 39 |
| 18 | 132 | 92 | 40 |
| 19 | 132 | 92 | 41 |
| 20 | 132 | 92 | 42 |
--------------------------------------------------------
pizza_menus
--------------------------
| id | menu_id | size_id |
--------------------------
| 25 | 92 | 1 |
| 26 | 92 | 1 |
| 27 | 92 | 1 |
| 28 | 92 | 2 |
--------------------------
This is my SQL code :
SELECT DISTINCT products.product_name, sizes.pizza_size_name
FROM products, menu_details, pizza_menus, sizes
WHERE products.product_id = menu_details.products_fk
AND menu_details.pizza_menus_fk = pizza_menus.menu_id
AND pizza_menus.size_id = sizes.pizza_size_id
AND menu_details.order_details_fk = 132
My desired output
----------------------------------
| product_name | pizza_size_name |
----------------------------------
| Italyan | Small |
| Classic | Small |
| Lamb | Small |
| Evi | Medium |
----------------------------------
Output that I get
----------------------------------
| product_name | pizza_size_name |
----------------------------------
| Italyan | Small |
| Classic | Small |
| Lamb | Small |
| Evi | Small |
| Italyan | Medium |
| Classic | Medium |
| Lamb | Medium |
| Evi | Medium |
----------------------------------
I know too many tables for such easy question but anyways
I really appreciate your help, thank you!
Associations between menu_details and pizza_menu were made wrong so I chaged menu_details to :
--------------------------------------------------------
| id | order_details_fk | pizza_menus_fk | products_fk |
--------------------------------------------------------
| 17 | 132 | 25 | 39 |
| 18 | 132 | 26 | 40 |
| 19 | 132 | 27 | 41 |
| 20 | 132 | 28 | 42 |
--------------------------------------------------------
And here is my new SQL:
SELECT DISTINCT products.product_name, sizes.pizza_size_name
FROM products, menu_details, pizza_menus, sizes
WHERE products.product_id = menu_details.products_fk
AND menu_details.pizza_menus_fk = pizza_menus.id
AND pizza_menus.size_id = sizes.pizza_size_id
AND menu_details.order_details_fk = 132

MySQL information from another table

I have the following SQL:
Select roleid , deity_level FROM default_jd_deity_role LIMIT 10;
That gives the output:
+--------+-------------+
| roleid | deity_level |
+--------+-------------+
| 1024 | 1 |
| 1043 | 54 |
| 1056 | 1 |
| 1057 | 54 |
| 1072 | 54 |
| 1074 | 45 |
| 1075 | 36 |
| 1088 | 45 |
| 1089 | 45 |
| 1104 | 27 |
+--------+-------------+
Then I have this SQL:
Select roleid , name FROM default_jd_ingame_roles LIMIT 22, 10
That gives the following output:
+--------+---------+
| roleid | name |
+--------+---------+
| 1024 | Hulu |
| 1043 | Cookiez |
| 1056 | Sam |
| 1057 | Sugar |
| 1072 | Leah |
| 1073 | Smexy |
| 1074 | Bam! |
| 1075 | Lexi |
| 1088 | OneShot |
| 1089 | Demono |
+--------+---------+
What I am trying to do is make deity_level add on to the second SQL Query like this:
+--------+---------+-------------+
| roleid | name | deity_level |
+--------+---------+-------------+
| 1024 | Hulu | 1 |
| 1043 | Cookiez | 54 |
| 1056 | Sam | 1 |
| 1057 | Sugar | 54 |
| 1072 | Leah | 54 |
| 1073 | Smexy | 45 |
| 1074 | Bam! | 36 |
| 1075 | Lexi | 45 |
| 1088 | OneShot | 45 |
| 1089 | Demono | 27 |
+--------+---------+-------------+
Try this:
Select a.roleid , a.deity_level, b.name
FROM default_jd_deity_role AS a
JOIN default_jd_ingame_roles AS b ON a.roleid=b.roleid
LIMIT 10
You can achieve this with a JOIN, like this:
SELECT main.roleid, roles.name, main.deity_level
FROM default_jd_deity_role main
LEFT JOIN default_jd_ingame_roles roles ON main.roleid = roles.roleid
LIMIT 22, 10
I'll leave two nice tutorials to get you started on JOINS:
http://www.sitepoint.com/understanding-sql-joins-mysql-database/
http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
You are looking for a JOIN query:
SELECT igr.roleid , igr.name, dr.diety_level
FROM default_jd_ingame_roles igr
JOIN default_jd_deity_role dr ON dr.roleid = igr.roleid