i have this two tables and i need to select everything from ENT table and display the name of the skill not the ID.
skill_1, skill_2, skill_3 refer to idSkill from skill table
Thank for you help
Ent Table :
+-------+---------+---------+---------+---------+
| idEnt | nameEnt | skill_1 | skill_2 | skill_3 |
+-------+---------+---------+---------+---------+
| 1 | testA | 1 | 2 | 3 |
| 2 | testB | 4 | 5 | 6 |
+-------+---------+---------+---------+---------+
Skill Table :
+---------+-------------+
| idSkill | nameSkill |
+---------+-------------+
| 1 | Storekeeper |
| 2 | Designer |
| 3 | Teacher |
| 4 | Baker |
| 5 | Gardener |
| 6 | Secretary |
+---------+-------------+
With this table structure you need to join the skill table 3 times on ent table, every time with different alias:
select idEnt, nameEnt, s1.nameSkill as skill1Name, s2.nameSkill as skill2Name, s3.nameSkill as skill3Name
from ent e
inner join skill s1 on e.skill_1=s1.idSkill
inner join skill s2 on e.skill_2=s2.idSkill
inner join skill s3 on e.skill_3=s3.idSkill
You may want to consider changing your table structure and have a connection table between ent and skill tables that hold idEnt - idSkill pairs.
Related
I have two tables users and services and i am try to write a single query that will create a new column skills. The values in the column skills will be the service_title which maps to the service_id stored in user_skills.
Below are the examples of a the tables used:
Table users:
+---------+---------------+----------------+----------------+
| id | user_fname | user_lname | user_skills |
+---------+---------------+----------------+----------------+
| 1 | kiran | bhattarai | 1,2 |
| 2 | sujan | bhattarai | 2,4 |
| 3 | manorath | dad | 1,2,3,4 |
| 4 | bhagawoti | mom | 2,3 |
+---------+---------------+----------------+----------------+
Table services:
+-----------------+------------------+
| service_id | service_title |
+-----------------+------------------+
| 1 | cook |
| 2 | clean |
| 3 | grocessery |
| 4 | teach |
+-----------------+------------------+
Currently i am using this query:
SELECT users.user_fname,
users.user_lname,
(SELECT GROUP_CONCAT(service_title)
FROM `services`
WHERE `service_id` IN (1,2,3,4)) as skills
FROM users
WHERE
id =3;
Result of the above query:
+---------------+----------------+----------------------------------------+
| user_fname | user_lname | skills |
+---------------+----------------+----------------------------------------+
| manorath | dad | cook,clean,grocessery,teach |
+---------------+----------------+----------------------------------------+
Instead of using the IN (1,2,3,4) I tried IN (users.user_skills) because the values in user_skills changes all the time and the result was:
+---------------+----------------+----------------------------------------+
| user_fname | user_lname | skills |
+---------------+----------------+----------------------------------------+
| manorath | dad | cook |
+---------------+----------------+----------------------------------------+
Every time a new service is added i have to add that service_id in the IN (1,2,3,4,new service id) of my query which is not a proper solution. I have already tried using php and another query to do solve this, the disadvantage of doing that is it is slowing down the process. How should i solve this problem in a single query.
You can use FIND_IN_SET() to JOIN the two tables.
SELECT
u.user_fname,
u.user_lname,
GROUP_CONCAT(s.service_title) as skills
FROM users u
LEFT JOIN services s
ON FIND_IN_SET(s.service_id, u.user_skills)
WHERE u.id = 3
Note that a JOIN with a FIND_IN_SET() condition cannot utilize any index. And that can lead to poor performance.
In general it's a bad idea to store relations in a separated string column. See Is storing a delimited list in a database column really that bad?.
You should normalize your design and create a separate table for your many-to-many relation. The table would look like
Table users_services:
+---------+------------+
| user_id | service_id |
+---------+------------+
| 1 | 1 |
| 1 | 2 |
| 2 | 2 |
| 2 | 4 |
| 3 | 1 |
| 3 | 2 |
| 3 | 3 |
| 3 | 4 |
| 4 | 2 |
| 4 | 3 |
+---------+------------+
And the query would be
SELECT
u.user_fname,
u.user_lname,
GROUP_CONCAT(s.service_title) as skills
FROM users u
LEFT JOIN users_services us ON us.user_id = u.id
LEFT JOIN services s ON s.service_id = us.service_id
WHERE u.id = 3
I need a help with mySQL SELECT query from multiple tables. I have got four tables: school, discipline, pupils and teams.
School table looks like:
+------+---------+---------------+----------+
| id | name | discipline_id | pupil_id |
+------+---------+---------------+----------+
| 1 | one | 2 | 5 |
+------+---------+---------------+----------+
| 2 | two | 3 | 8 |
+------+---------+---------------+----------+
| 3 | three | 4 | 12 |
+------+---------+---------------+----------+
Discipline table looks like:
+------+---------+
| id | name |
+------+---------+
| 1 | math |
+------+---------+
| 2 | bio |
+------+---------+
| 3 | liter |
+------+---------+
| 4 | geo |
+------+---------+
Teams table looks like:
+------+---------+---------------+-----------+
| id | name | school_id | member_id |
+------+---------+---------------+-----------+
| 1 | T1 | 1 | 3 |
+------+---------+---------------+-----------+
| 2 | T2 | 3 | 3 |
+------+---------+---------------+-----------+
| 3 | T3 | 2 | 9 |
+------+---------+---------------+-----------+
The result of disciplines I need to get with a "SELECT from discipline..." query by "member_id = 3" is:
+-----------------+---------------+
| discipline_name | discipline_id |
+-----------------+---------------+
| bio | 2 |
+-----------------+---------------+
| geo | 4 |
+-----------------+---------------+
By matching member's school and then getting its discipline, if it makes sense...Is it possible to do with just one mySQL query?
Type of: member_id 3 => school_id 1,3 => discipline_id = show related disciplines names and ids which are 2, 4
Thank you very much...
Your goal is not clear or makes no sense to me.
But here is what you are literally asking for:
SELECT
s.discipline_id
d.name
FROM teams t
LEFT JOIN school s
ON s.id = t.school_id
LEFT JOIN discipline d
ON d.id = s.discipline_id
WHERE t.member_id = 3
I have a database with 3 tables: students, courses and mistakes. I have one joining table (csm) where I connect the 3 tables. I am supposing mistakes are the same for each course.
Table Courses
+----------+---------------+
| crs_id | crs_name |
+----------+---------------+
| 1 | HTML |
| 2 | PHP |
| 3 | Python |
+----------+---------------+
Table Students
+----------+---------------+---------------+
| stu_id | stu_firstname | stu_lastname |
+----------+---------------+---------------+
| 1 | Tina | Turner |
| 2 | Lisa | Laroi |
| 3 | Dina | Donna |
| 3 | Jim | Leduc |
+----------+---------------+---------------+
Table Mistakes
+----------+---------------+------------+
| mis_id | mis_name | mis_weight |
+----------+---------------+------------+
| 1 | No camelCase | 7 |
| 2 | No brackets | 10 |
| 3 | Operator mist.| 12 |
+----------+---------------+------------+
Joining table CSM
+----------+------------+------------+------------+
| csm_id | fk_crs_id | fk_stu_id | fk_mis_id |
+----------+------------+------------+------------+
| 1 | 1 | 1 | 1 |
| 2 | 1 | 1 | 3 |
| 3 | 2 | 3 | 1 |
| 4 | 3 | 2 | 2 |
| 5 | 3 | 2 | 1 |
| 6 | 3 | 3 | 1 |
+----------+------------+------------+------------+
If I select a specific course, I want to get a list of ALL students with the minus points for this course. So I also want to get the students with no result in the joining table csm.
The closest result I got is with the following sql statement:
select stu_firsname, stu_lastname, csm.*, sum(mis_weight)
from students s
left join crs_stu_mis csm on s.stu_id = csm.fk_stu_id
left join mistakes m on csm.fk_mis_id = m.mis_id
where fk_crs_id = 4 or fk_crs_id is null
group by stu_firstname;
With this I get the sum of the mistakes for a certain course and also the students who don't have any records in CSM table, but some results are missing. For example, this doesn't show the students who have records in the CSM table, but not for the requested course.
How do I get these students in my result table?
In your query :
left join crs_stu_mis csm on s.stu_id = csm.fk_stu_id`
...
where fk_crs_id = 4 or fk_crs_id is null
This is not exactly what you want, since this condition will filter out students that have records in the csm table for only courses other than 4. You want to move that condition to the corresponding LEFT JOIN:
left join crs_stu_mis csm on s.stu_id = csm.fk_stu_id AND csm.fk_crs_id = 4
Another potential source of problems is the way the query handles aggregation. There are non-aggregated columns in the SELECT clause that do not appear in the GROUP BY clause. This syntax is not good SQL coding practice, and is not supported anymore since version 5.7 of MySQL. I assumed that you want to one record in the result for each student.
Query:
select
s.stu_firstname,
s.stu_lastname,
sum(m.mis_weight) total_misses_weight
from
students s
left join crs_stu_mis csm on s.stu_id = csm.fk_stu_id AND csm.fk_crs_id = 3
left join mistakes m on csm.fk_mis_id = m.mis_id
group by
s.stu_id,
s.stu_firstname,
s.stu_lastname
Demo on DB Fiddle for course id 3:
| stu_firstname | stu_lastname | total_misses_weight |
| ------------- | ------------ | ------------------- |
| Tina | Turner | |
| Lisa | Laroi | 17 |
| Dina | Donna | 7 |
| Jim | Leduc | |
if your primary data's is in CSM table, try this:
select s.stu_firsname, s.stu_lastname, csm.*, sum(m.mis_weight) from crs_stu_mis csm
join students s on s.stu_id = csm.fk_stu_id
join mistakes m on csm.fk_mis_id = m.fou_id
csm.fk_crs_id = 4
group by s.stu_naam;
Second case:
Your data's can affected by group by attribute, try attribute that it is not NULL , ex:
select s.stu_firsname, s.stu_lastname, csm.*, sum(m.mis_weight) from crs_stu_mis csm
join students s on s.stu_id = csm.fk_stu_id
join mistakes m on csm.fk_mis_id = m.fou_id
csm.fk_crs_id = 4
group by csm.csm_id;
Lets say that I have something table like this:
<b>Name</b>
+---------+--------+
| name_id | name |
+---------+--------+
| 5 | Betti |
| 6 | Derry |
| 7 | Alfred |
| 8 | Elsie |
| 9 | Cinta |
+---------+--------+
<b>Goods</b>
+----------+-----------+
| goods_id | goods |
+----------+-----------+
| 1 | Computer |
| 2 | AC |
| 3 | Microwave |
| 4 | TV |
+----------+-----------+
<b>Transaction</b>
+-------+---------+----------+
| ai_id | name_id | goods_id |
+-------+---------+----------+
| 1 | 7 | 2 |
| 2 | 5 | 4 |
| 3 | 9 | 3 |
+-------+---------+----------+
I want to replace name_id column on Transaction table with name column on Name table with corresponding name_id column and so for goods_id to produce something similar to this table:
<b>Transaction</b>
+-------+--------+-----------+
| ai_id | name | goods |
+-------+--------+-----------+
| 1 | Alfred | AC |
| 2 | Betti | TV |
| 3 | Cinta | Microwave |
+-------+--------+-----------+
If you're looking to just display the information rather than actually "replacing" your tables with new ones, then you could use a SELECT query with a simple INNER JOIN. This way you can display columns from multiple tables.
SELECT T.ai_id, N.Name, G.goods
FROM Transaction T
INNER JOIN Name N ON N.name_id = T.name_id
INNER JOIN Goods G ON G.goods_id = T.goods_id;
Try with inner join
SELECT T.ai_id,N.name,G.goods
FROM Transaction as T
INNER JOIN Goods as G ON T.goods_id = G.goods_id
INNER JOIN Name as N ON N.name_id = T.name_id;
Try this one
select tb3.ai_id,tb2.name,tb1.goods from Goods tb1,Name tb2,Transaction tb3 where tb3.name_id=tb2.name_id and tb3.goods_id=tb1.goods_id order by tb3.ai_id
try this:
SELECT C.ai_id,A.name,B.goods
FROM Transaction C
INNER JOIN Name A
ON A.name_id=C.name_id
INNER JOIN Goods B
ON B.goods_id=C.goods_id;
http://sqlfiddle.com/#!2/3c5f3/8
I'm new to relational sql. I'm trying to figure out a query to return the names of customers who have more than one type of account.
customers:
+------------+--------------+
| cid | Name |
+------------+--------------+
| 1 | Bob |
| 2 | John |
| 3 | Jane |
+------------+--------------+
accounts:
+------------+--------------+
| aid | type |
+------------+--------------+
| 1 | Checking |
| 2 | Saving |
| 3 | CD |
+------------+--------------+
transactions:
+------------+--------------+--------------+
| tid | cid | aid |
+------------+--------------+--------------+
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 1 | 2 |
| 4 | 2 | 3 |
| 5 | 3 | 1 |
+------------+--------------+--------------+
With these tables, the query should return Bob and John. I'm having some trouble with how to write such a query. More specifically, how do I keep count of how many accounts a customer has and how do I compare if the accounts are different without adding a new column to the table?
Okay, this seems to work in SQL Fiddle with my test data structure. Try it out with your real data structure and see if it gives you what you're looking for.
SELECT name FROM customers c WHERE EXISTS(
SELECT DISTINCT aid FROM transactions
WHERE cid = c.cid
HAVING COUNT(DISTINCT aid)>1
)