return multiple rows in subquery mysql - mysql

i am new in mysql and stuck on a query.i want all the records of one table and multiple tags from other table that match with one column of first table.
select A.*,(select B.tag from crm_tags B where tag_id in (A.tags)) from crm_stores A;
there are multiple stores in crm_stores and each store has multiple tags in crm_tags. i want all details of store and each tag of store in one query.
when i tried the above query, it generates error : subquery returns multiple rows. please help, how to solve that problem
The tags in crm_stores are like "2098,2063",means multiple tags are comma seprated. While crm_tags has seprated entries
Thanks in advance
this is my first table crm_stores
+----------+-------+--------+-----------+----------+-
| store_id | guest | budget | tags | discount |
+----------+-------+--------+-----------+----------+-
| 23 | 5 | 1000 | 2098,2063 | 50% |
+----------+-------+--------+-----------+----------+-
this is my second table crm_tags
+--------+--------------+
| tag_id | tag |
+--------+--------------+
| 2063 | Chinese |
| 2098 | North Indian |
+--------+--------------+

use a join:
SELECT A.*, B.tag
FROM crm_stores A
LEFT JOIN crm_tags B ON A.tags LIKE concat(concat('%',B.tag_id),'%')
new mysql fiddle:
http://sqlfiddle.com/#!9/dedeb1/7/0

Related

Select count with value from different tables

I want to count all entries in one table grouped by the user id.
This is the query I used which works fine.
select uuid_mapping_id, count(*) from t_message group by uuid_mapping_id;
and these are the results:
+-----------------+----------+
| uuid_mapping_id | count(*) |
+-----------------+----------+
| 1 | 65 |
| 4 | 277 |
Now I would like to display the actual user name, instead of the ID.
To achieve this I would need the help of two different tables.
The table t_uuid_mapping which has two columns:
uid_mapping_id, which equals uuid_mapping_id in the other table.
And f_uuid which is also unique but completely different.
f_uuid can also be found in another table t_abook which also contains the names in the column f_name.
The result I am looking for should be:
+-----------------+----------+
| f_name | count(*) |
+-----------------+----------+
| admin | 65 |
| user1 | 277 |
I am new to the database topic and understand that this could be achieved by using JOIN in the query, but to be honest I did not completely understand this yet.
if I understand you correctly:
SELECT tm.f_name, COUNT(*) as count
FROM t_message tm
LEFT JOIN t_abook ta ON (tm.uuid_mapping_id = ta.uid_mapping_id)
GROUP BY tm.f_name

Left Join takes very long time on 150 000 rows

I am having some difficulties to accomplish a task.
Here is some data from orders table:
+----+---------+
| id | bill_id |
+----+---------+
| 3 | 1 |
| 9 | 3 |
| 10 | 4 |
| 15 | 6 |
+----+---------+
And here is some data from a bills table:
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
+----+
I want to list all the bills that have no order associated with.
In order to achieve that, I thought that the use of LEFT JOIN was appropriated so I wrote this request:
SELECT * FROM bills
LEFT JOIN orders
ON bills.id = orders.bill_id
WHERE orders.bill_id IS NULL;
I thought that I would have the following result:
+----------+-----------+----------------+
| bills.id | orders.id | orders.bill_id |
+----------+-----------+----------------+
| 2 | NULL | NULL |
| 5 | NULL | NULL |
+----------+-----------+----------------+
But I can't reach the end of the request, it has run more than 5 minutes without result, I stopped the request because this can't be a production time anyway.
My real dataset has more than 150 000 orders and 100 000 bills. Is the dataset too big?
Is my request wrong somewhere?
Thank you very much for your tips!
EDIT: side note, the tables have no foreign keys defined... *flies away*
Your query is fine. I would use table aliases in writing it:
SELECT b.*
FROM bills b LEFT JOIN
orders o
ON b.id = o.bill_id
WHERE o.bill_id IS NULL;
You don't need the NULL columns from orders, probably.
You need an index on orders(bill_id):
create index idx_orders_billid on orders(bill_id);
By your where statement, I assume your looking for orders that have no bills.
If that's the case you don't need to do a join to the bills table as they would by definition not exist.
You will find
SELECT * FROM orders
WHERE orders.bill_id IS NULL;
A much better performing query.
Edit:
Sorry I missed your "I want to list all the bills that have no order associated with." when reading the question. As #gordon pointed out an index would certainly help. However if changing the scheme is feasible I would rather have a nullable bill.order_id column instead of a order.bill_id because you won't need a left join, an inner join would suffice to get order bills as it would be a quicker query for your other assumed requirements.

Mysql: how to return value or empty string from column ids in table (multi table)

I'M trying to extract all information into my table, but I need to change id, when available, to the name into another table.
I have 1 table like that:
|------------------------------|
|-id-|-systems-|-remote-|-deco-|
| 1 | NULL | 3 | |
| 2 | 21 | NULL | 2 |
|-------------------------------
each column like "systems" / "remote" / "deco" refer to an id into another table
I know how to use INNER JOIN. But if I use that, I got an empty result because the value need to be appears into the others tables.
ex.:
SELECT qd.id,s.name as systems,r.name as remote, d.name as deco
FROM `quote_data` qd
INNER JOIN systems s ON qd.systems=s.id
INNER JOIN remote r ON qd.remote=r.id
INNER JOIN deco d ON qd.deco=d.id
I got empty result.
In the best words, I need to do something like:
|------------------------------|
|-id-|-systems-|-remote-|-deco-|
| 1 | | R42 | |
| 2 | GTV | | B21 |
|-------------------------------
Also, I use innoDB table
Any Idea how to fix that?

MYSQL query fetching DATA from two table using IN method one as composition of multiple data

I have two tables
one as td_job which has these structure
|---------|-----------|---------------|----------------|
| job_id | job_title | job_skill | job_desc |
|------------------------------------------------------|
| 1 | Job 1 | 1,2 | |
|------------------------------------------------------|
| 2 | Job 2 | 1,3 | |
|------------------------------------------------------|
The other Table is td_skill which is this one
|---------|-----------|--------------|
|skill_id |skill_title| skill_slug |
|---------------------|--------------|
| 1 | PHP | 1-PHP |
|---------------------|--------------|
| 2 | JQuery | 2-JQuery |
|---------------------|--------------|
now the job_skill in td_job is actualy the list of skill_id from td_skill
that means the job_id 1 has two skills associated with it, skill_id 1 and skill_id 2
Now I am writing a query which is this one
SELECT * FROM td_job,td_skill
WHERE td_skill.skill_id IN (SELECT td_job.job_skill FROM td_job)
AND td_skill.skill_slug LIKE '%$job_param%'
Now when the $job_param is PHP it returns one row, but if $job_param is JQuery it returns empty row.
I want to know where is the error.
The error is that you are storing a list of id's in a column rather than in an association/junction table. You should have another table, JobSkills with one row per job/skill combination.
The second and third problems are that you don't seem to understand how joins work nor how in with a subquery works. In any case, the query that you seem to want is more like:
SELECT *
FROM td_job j join
td_skill s
on find_in_set(s.skill_id, j.job_skill) > 0 and
s.skill_slug LIKE '%$job_param%';
Very bad database design. You should fix that if you can.

MySQL get data from three tables using one id

I have three different tables, which have following structure:
Food
ID | title
---+----------
1 | sandwich
2 | spaghetti
Ingridients
ID | food_reference | type | location | bought
----+----------------+------+----------+----------
100 | 1 | ham | storeA | 11-1-2013
101 | 1 | jam | storeB | 11-1-2013
102 | 2 | tuna | storeB | 11-6-2013
Tags
ID | food_reference | tag
----+----------------+-----
1000| 1 | Tag
1001| 1 | Tag2
1002| 2 | fish
and using one select I want to get all information from these three tables (title,type,location,bought,tag) for one specific ID.
I have tried something like
SELECT food.*,ingridients.*,tags.* FROM food
JOIN ingridients
ON :id=ingridients.food_reference
JOIN tags
ON :id=tags.food_reference
WHERE id=:id
BUT this query returns for id=1 only one row from ingridients and tags even though there are two matching rows (ham and jam, Tag and Tag2). Could you tell me what am I doing wrong?
EDIT: I tried LolCoder's solution, but I still got only one result, even though in fiddle it seems to work. However I tried :
SELECT F.*, group_concat(I.type), group_concat(I.location),
group_concat(I.bought), group_concat(T.tag)
FROM feeds F
INNER JOIN ingridients I
ON :id = I.food_reference
INNER JOIN tags T
ON :id=T.food_reference
WHERE F.id=:id
This finds data from ALL matching rows, but several times, i.e. I get (for id=1)
sandwich,ham,ham,ham,jam,jam,jam,tag,tag,tag,tag2,tag2,tag2
EDIT2: magic happened and LolCoder's solution works, so thank you :-)
Try with this query:
SELECT food.*,ingridients.*,tags.* FROM food
JOIN ingridients
ON food.id=ingridients.food_reference
JOIN tags
ON food.id=tags.food_reference
WHERE food.id=1
Check SQLFIDDLE
use alias with joins as.column name