MySQL - Join on comma-separated field - mysql

I would like to do some new stuff (for me it's new, bc. I'm just a MySQL-beginner) and I did not find a solution for this.
I got these entries in my database:
mytable_items
id | title | catids
1 | test | 32,14
mytable_categories
id | title
32 | Test-Category
14 | Another-Category
Now I would like to join this stuff: Show all data from mytable_items - also show the assigned categories (their titles)
The result should be:
1 | test | Test-Category, Another-Category
How can I solve this?
Thanks a lot in advance :-)

Try this:
SELECT m.id,group_concat(mc.title)
FROM mytable_items m
JOIN mytable_categories mc
ON FIND_IN_SET(mc.id,m.catids)
group by
m.id
SQL FIDDLE DEMO

You should use different entities for each CatID. Then you can join both tables and use Group Concat.

Try this:
Select *
from mytable_items a
join mytable_categories b on a.id = b.id
This will join the data and show it correctly.

Related

Join two tables and using computed columns

I have two simple tables in a database.
The schema looks like this:
I have created an SQL-Fiddle with some example-data.
Link: http://sqlfiddle.com/#!9/c5e87c/2
At first I want to simple query for all Printers that should get connected to a Computer.
I select the table computermapping and query for a ComputerGUID like this:
SELECT PrinterGUID
FROM computermapping
WHERE ComputerGUID = '5bec3779-b002-46ba-97c4-19158c13001f'
This is OK. At second, I want to join the table "computerdefaultprinter".
I use a LEFT JOIN on the ComputerGUID like this:
SELECT computermapping.PrinterGUID
FROM computermapping
LEFT JOIN computerdefaultprinter ON computerdefaultprinter.ComputerGUID = computermapping.ComputerGUID
WHERE computermapping.ComputerGUID = '5bec3779-b002-46ba-97c4-19158c13001f'
Also OK.
Finally I want to know, which Printer will be the Default-Printer. A Computer can only have one Default-Printer. Using my sample data in the SQL-Fiddle I want the output to be like this:
PrinterGUID | isDefaultPrinter
--------------------------------------------------------
5549f63f-e02f-4685-a976-96b50c299bed | 1
957b7233-e590-4e7d-aed6-aee0573fc3a8 | 0
5106f1f7-068f-463f-9b76-7cc0ba017184 | 0
I used something in the past like:
SELECT computermapping.PrinterGUID, ( computerdefaultprinter.PrinterGUID IS NOT NULL) as isDefaultPrinter
...
But I can't get it to work anymore. I haven't used SQL for some years now.
Currently I am using MySQL, if this is important.
Could you please help me to solve this?
Thank you.
PS: I had problems to find an adequate title for my request. I don't know if using "computed columns" mentioned in the title is correct.
You are missing the condition that relates the PrinterGUIDs of the 2 tables in the ON clause:
SELECT m.PrinterGUID,
p.PrinterGUID IS NOT NULL AS isDefaultPrinter
FROM computermapping AS m LEFT JOIN computerdefaultprinter AS p
ON p.ComputerGUID = m.ComputerGUID AND p.PrinterGUID = m.PrinterGUID
WHERE m.ComputerGUID = '5bec3779-b002-46ba-97c4-19158c13001f'
See the demo.
Results:
> PrinterGUID | isDefaultPrinter
> :----------------------------------- | ---------------:
> 5549f63f-e02f-4685-a976-96b50c299bed | 1
> 957b7233-e590-4e7d-aed6-aee0573fc3a8 | 0
> 5106f1f7-068f-463f-9b76-7cc0ba017184 | 0

Static SQL query replace to dynamic column

I have following query:
http://www.sqlfiddle.com/#!9/752e34/3
This query use SELECT in SELECT queries.
"SELECT a.*
,(SELECT s.value FROM tbl_scd AS s WHERE s.tag_id = 1 AND s.main_id = a.id ORDER BY s.date_time DESC LIMIT 1) AS title
,(SELECT s.value FROM tbl_scd AS s WHERE s.tag_id = 2 AND s.main_id = a.id ORDER BY s.date_time DESC LIMIT 1) AS alt
FROM tbl_main AS a
WHERE 1;"
Now I'm looking for a solution to add a new row into tbl_tag without change the above query (that the SELECT in SELECT part will be dynamic) to get a reference to tbl_tag
To get this:
+----+---------------+-----------+-----------+--------------+
| id | date | title | alt | new_column |
+----+---------------+-----------+-----------+--------------+
| 1 | 2018-10-10 | test1-1 | test1-3 | NULL |
| 2 | 2018-10-11 | test2-1 | test2-1 | NULL |
+----+---------------+-----------+-----------+--------------+
It would be great to get an idea or help.
Thanks
Your last comment on your question about using JOIN makes it clearer to me (I think) what you are after. JOINs will definitely help you a lot here, in place of the rather cumbersome query you are currently using.
Try this:
SELECT
tbl_main.date,
tblA.value AS title,
tblB.value AS alt
FROM
tbl_main
INNER JOIN (SELECT main_id, tag_id, value
FROM tbl_scd
INNER JOIN tbl_tag ON (tbl_scd.tag_id = tbl_tag.id)
WHERE tbl_tag.name = 'title') tblA
ON (tbl_main.id = tblA.main_id)
INNER JOIN (SELECT main_id, tag_id, value
FROM tbl_scd
INNER JOIN tbl_tag ON (tbl_scd.tag_id = tbl_tag.id)
WHERE tbl_tag.name = 'alt') tblB
ON (tbl_main.id = tblB.main_id);
I think this will get you much closer to a general solution to what it looks like you are trying to achieve, or at least point you in a good direction with using JOINs.
I also think you might benefit from re-thinking your database design, because this kind of pivoting rows from one table into columns in a query output can be an indicator that the data might be better off structured differently.
In any case, I hope this helps.

Mysql Update where Count Distinct return more than one row

I have two tables, the first one with a list of guides names, chapter and topic, that change with time when new guides are added with or without the same name, lets called "guides", sort of this:
|---Name---|---Chapter---|---Topic---|
|The Hearth| 1 |Educational|
|The Hearth| 2 |Educational|
|The Hearth| 3 |Educational|
|The Brain | 1 |Maths |
and another table where i assign a ID to each guide, lets called "resume", something like this
|---id---|---Name---|---Topic---|
| 1 |The Hearth|Educational|
| 2 |The Brain |Maths |
Now when a guide of the same name is added to "guides" and it have a dif topic, like:
|---Name---|---Chapter---|---Topic---|
|The Hearth| 4 |Tales |
i need to update the "resume" table to:
|---id---|---Name---|---Topic---|
| 1 |The Hearth|MIXED |
| 2 |The Brain |Maths |
i have been trying different ways and this is what i have so far:
UPDATE resume J INNER JOIN guides P ON J.name = P.name SET J.topic = "Mixed"
WHERE J.topic != P.topic AND (SELECT COUNT(DISTINCT a.topic)
FROM guides a
JOIN guides b
ON a.name = b.name
AND a.topic != b.topic
GROUP BY a.name
HAVING COUNT(DISTINCT a.topic) > 1)
All is ok while there is just one record, but if there was added two guides with dif topics the subquery returns more than one row and it dont make the update. I know i can solve this with a php loop, but im sure there must be a way to handle this on the query itself, i would appreciate any lights on this.
Thanks in advance
You can do a select count first and join later to optimize the query speed:
UPDATE resume J
INNER JOIN (
SELECT COUNT(DISTINCT A.topic) AS num, A.name
FROM guides A
GROUP BY A.name
HAVING COUNT(DISTINCT A.topic)>1) AS P ON J.name = P.name
SET J.topic = "Mixed"

Select Data from two tables where ID on both tables are same

Okay I have two tables called subobject: parentID, objectName, subID(primary) and subrelation: ID, className
parentID | objectName | subID ID| className|
_____________________________ ______________
84 | Test | 14 14| BOM
84 | Test2 | 15 15| Schematics
I want to match SubID with ID from both tables depending if they are the same values, then iterate all the values that are the same. Whats the query to do this in Mysql.
this is how I want it to look:
subobjectNAME:
--RelatedClass
--RelatedClass2
etc.
I know this is has something to do with JOIN and this is the mysql Query im using but its not working
"SELECT * from subrelation inner join subobject on subrelation.ID = subobject.subID"
also my while loop to grab this
while($join = mysqli_fetch_assoc($join))
JOIN the two tables:
SELECT
so.objectName,
sr.ClassName
FROM subobject AS so
INNER JOIN subrelation AS sr ON so.subId = sr.ID;
See it in action here:
SQL Fiddle Demo
Also, see the following post for more info about the different types of JOINs:
A Visual Explanation of SQL Joins.
select
a.objectName, b.className
from
subobject a
left join
subrelation b on a.subID = b.ID
Use a Join
SELECT
subobject.ObjectName,
subrelation.ClassName
FROM
subobject
INNER JOIN
subrelation ON subobject.subID = subrelation.ID
You can find information on SQL Joins here:
http://en.wikipedia.org/wiki/Join_(SQL)
And information from the MySQL manual on Joins:
http://dev.mysql.com/doc/refman/5.0/en/join.html

MySql query combine results from 2 tables

I try to combine data from 2 tables by a mysql join but I look likes, I don't receive the results from the second table at all.
Table structre #1 (site_hosters);
+------------+--------------+--------+
| host_id | name | prio |
+------------+--------------+--------+
| 1 | site.com | 0 |
+------------+--------------+--------+
Table structure #2 (site_date);
+------------+--------------+--------+
| id | hoster | page |
+------------+--------------+--------+
| 1 | site.com | http:..|
+------------+--------------+--------+
What I try to get is a result like 'id, host_id, name, ....etc';
When I try the follow query, it doesn't take host_id and prio in the query result.
It looks, the join has no effect at all by query it.
My query:
SELECT
site.id,
site.hoster,
site.page,
FROM site_data as site
INNER JOIN site_hosters hoster
ON site.hoster = hoster.name
I hope someone can help me with this one.
Kind regards,
Nick
You have to name the columns you want to select. Add the site_hosters columns like that:
SELECT
site.id,
site.hoster,
site.page,
hoster.host_id,
hoster.prio
FROM site_data as site
INNER JOIN site_hosters hoster ON site.hoster = hoster.name
You could do
SELECT
site.*,
hoster.*
FROM site_data as site
INNER JOIN site_hosters hoster ON site.hoster = hoster.name
This will return all fields, however, you may only want something like
site.id, ste.hoster, site.page, hoster.prio as your fields.
Just list required fields in SELECT:
SELECT site.id, hoster.host_id, hoster.name, site.hoster, site.page
FROM site_data AS site
INNER JOIN site_hosters AS hoster ON site.hoster = hoster.name