I need help for many to many relation query - mysql

I have working on database for dictionary project. I have to store a word and meaning with many to many relationship.
Below I have mentioned the sample with my table structure. I hope the table structure is right, but I don't know how to select all meanings for single word while user searching.
And also I have to write a query to select all word and synonyms linked to a single meaning. And also I have to write a query to select all meaning and synonyms linked to a single word.
word_table
+----+------+
| id | word |
+----+------+
| 1 | A |
| 2 | B |
| 3 | C |
+----+------+
meaning_table
+----+--------+
| id | meaning|
+----+--------+
| 1 | X |
| 2 | Y |
| 3 | Z |
+----+--------+
word_meaning_table
+---------+-----------+
| word_id | meaning_id|
+---------+-----------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 3 |
| 3 | 2 |
| 3 | 3 |
+---------+-----------+
synonyms_table
+----+--------+
| id | synonys|
+----+--------+
| 1 | aa |
| 2 | bb |
| 3 | cc |
+----+--------+
word_synonyms_table
+---------+-----------+
| word_id | synonym_id|
+---------+-----------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
+---------+-----------+
Expected output should be like this.
If user searching for a word "A" in word table the result should be
Result for word "A"
+----+----------+---------+
| word| meaning | synonys |
+----+----------+---------+
| A | X | aa |
| A | Y | bb |
| A | Z | cc |
+----+----------+---------+

You just need many joins:
SELECT w.word,m.meaning,s.synonys
FROM word_table w
INNER JOIN word_meaning_table wm
ON(w.id = wm.word_id)
INNER JOIN meaning_table m
ON(wm.meaning_id = m.id)
INNER JOIN word_synonyms_table ws
ON(w.id = ws.word_id)
INNER JOIN synonyms_table s
ON(ws.synonym_id = s.id)
Let me reffer you to this document that explain all about join syntax's.

Related

Combine two tables into one in MySQL

Suppose I have two tables named users and offers
users table
+----+----------+-----------+
| id | username | role |
+----+----------+-----------+
| 1 | A | client |
+----+----------+-----------+
| 2 | B | client |
+----+----------+-----------+
| 3 | C | candidate |
+----+----------+-----------+
| 4 | D | candidate |
+----+----------+-----------+
| 5 | E | candidate |
+----+----------+-----------+
offers table
+----+-----------+--------------+
| id | client_id | candidate_id |
+----+-----------+--------------+
| 1 | 1 | 3 |
+----+-----------+--------------+
| 2 | 2 | 4 |
+----+-----------+--------------+
| 3 | 1 | 5 |
+----+-----------+--------------+
| 4 | 2 | 3 |
+----+-----------+--------------+
| 5 | 2 | 5 |
+----+-----------+--------------+
I want to create a query to combine offers table with users table, like
+----+-----------+-----------------+--------------+--------------------+
| id | client_id | client_username | candidate_id | candidate_username |
+----+-----------+-----------------+--------------+--------------------+
| 1 | 1 | A | 3 | C |
+----+-----------+-----------------+--------------+--------------------+
| 2 | 2 | B | 4 | D |
+----+-----------+-----------------+--------------+--------------------+
| 3 | 1 | A | 5 | E |
+----+-----------+-----------------+--------------+--------------------+
| 4 | 2 | B | 3 | C |
+----+-----------+-----------------+--------------+--------------------+
| 5 | 2 | B | 5 | E |
+----+-----------+-----------------+--------------+--------------------+
I have written 2 queries that are working separately, but I want to combine these into one table.
SELECT offers.candidate_id, users.username AS candidate_username
FROM offers INNER JOIN users ON offers.candidate_id = users.id;
SELECT offers.client_id, users.username AS client_username
FROM offers INNER JOIN users ON offers.client_id = users.id;
You can try below -
SELECT offers.candidate_id,
a.username AS client_username,a1.username as candidate_username
FROM offers left JOIN users a ON offers.client_id = a.id
left join users a1 ON offers.candidate_id = a1.id
You can use Left Join for this purpose like:
SELECT offers.candidate_id,
a.username AS client_username,a1.username AS candidate_username
FROM offers left JOIN users a ON offers.client_id = a.id OR offers.candidate_id = a.id;

How to make a selection from two tables?

I have table 'articles'
+-------------+
| articles |
+----+--------+
| id | title |
+----+--------+
| 1 | title1 |
+----+--------+
| 2 | title2 |
+----+--------+
| 3 | title3 |
+----+--------+
table 'catalogue'
+---------------------+
| catalogue |
+----+--------+-------+
| id | group | name |
+----+--------+-------+
| 1 | group1 | name1 |
+----+--------+-------+
| 2 | group1 | name2 |
+----+--------+-------+
| 3 | group2 | name3 |
+----+--------+-------+
| 4 | group2 | name4 |
+----+--------+-------+
binding table 'bindTable'
+------------+--------------+-------+
| bindTable |
+------------+--------------+-------+
| id_article | id_catalogue | value |
+------------+--------------+-------+
| 1 | 2 | 1 |
+------------+--------------+-------+
| 1 | 3 | 4 |
+------------+--------------+-------+
| 3 | 1 | 2 |
+------------+--------------+-------+
| 3 | 3 | 1 |
+------------+--------------+-------+
| 3 | 4 | 3 |
+------------+--------------+-------+
and i need to get result as in table 'result', where i can get pairs "catalogue_name : value" for selected item from table 'article'
+-----------------------------------------------------+
| result |
+------------+---------------+----------------+-------+
| article_id | article_title | catalogue_name | value |
+------------+---------------+----------------+-------+
| 1 | title1 | group1_name2, | 1 |
| | | group2_name3 | 4 |
+------------+---------------+----------------+-------+
| 3 | title3 | group1_name1, | 2 |
| | | group2_name3, | 1 |
| | | group2_name4 | 3 |
+------------+---------------+----------------+-------+
Can anyone tell me a query string with one DB query? Thank you for attention.
My vision:
SELECT b.id_article, a.title, c.group, c.name, b.value
FROM bindTable b
JOIN articles a ON a.id = b.id_articles
JOIN catalogue c ON c.id = b.id_catalogue
WHERE b.id_article = 1
but i need one row with pairs c.name&b.value for one a.id
A select with inner join
select a.article_id, a.article_title, b.catalogue_name, b.value
from bindTable as c
inner join articles as a on a.id = c. article_id
inner join catalogues as b on c. id_catalogue = b.id
This should do it.
SELECT articles.id AS article_id,
articles.title AS article_title,
CONCAT_WS('_', catalogue.group, catalogue.name) AS catalogue_name,
bindTable.value AS value
FROM bindTable
INNER JOIN articles ON bindTable.id_article = articles.id
INNER JOIN catalogue ON bindTable.id_catalogue = catalogue.id

Select rows from table by id of a left join table

I have 3 tables:
+-------------+ +-------------+ +-------------+
| hotel | | hot_cat | | category |
+------+------+ +------+------+ +-------------+
| id | name | | hid | cid | | id | name |
+------+------+ +------+------+ +-------------+
| 1 | X | | 1 | 1 | | 1 | cat1 |
+------+------+ +------+------+ +-------------+
| 2 | Y | | 1 | 2 | | 2 | cat2 |
+------+------+ +------+------+ +-------------+
| 3 | Z | | 2 | 2 | | 3 | cat3 |
+------+------+ +------+------+ +-------------+
| 2 | 3 | | 4 | cat4 |
+------+------+ +-------------+
| 2 | 4 |
+------+------+
I want to select hotels where category is some value, but with all other categories assigned to this hotel. I have this query:
SELECT hot.*,GROUP_CONCAT(cat.name SEPARATOR '<br>') AS cats
FROM hotel hot
LEFT JOIN hot_cat hc ON hc.hid = hot.id
LEFT JOIN category cat ON cat.id = hc.cid
WHERE cat.id = 2
GROUP BY hot.id
So I get this:
+------+------+-------------------------+
| id | name | cats |
+------+------+-------------------------+
| 1 | X | 'cat2' |
+------+------+-------------------------+
| 2 | Y | 'cat2' |
+------+------+-------------------------+
What I want to achieve:
+------+------+-------------------------+
| id | name | cats |
+------+------+-------------------------+
| 1 | X | 'cat1<br>cat2' |
+------+------+-------------------------+
| 2 | Y | 'cat2<br>cat3<br>cat4' |
+------+------+-------------------------+
I also want it to work without the where clause and get hotels without category assigned:
+------+------+-------------------------+
| id | name | cats |
+------+------+-------------------------+
| 1 | X | 'cat1<br>cat2' |
+------+------+-------------------------+
| 2 | Y | 'cat2<br>cat3<br>cat4' |
+------+------+-------------------------+
| 3 | Z | '' |
+------+------+-------------------------+
Start your query at the hot_cat table, and then join into hotel. It's one extra jump through the tables, but it solves the problem.
SELECT hot.*,GROUP_CONCAT(cat.name SEPARATOR '<br>') AS cats
FROM hot_cat hc1
LEFT JOIN hotel hot ON hc1.hid = hot.id
LEFT JOIN hot_cat hc ON hc.hid = hot.id
LEFT JOIN category cat ON cat.id = hc.cid
WHERE hc1.id = 2
GROUP BY hot.id
If, instead, you don't need the WHERE then you can just use your existing query without the WHERE clause.

A simple many to many SQL example

I'm trying to figure out a good way of doing an SQL query that returns a table of user names and their choices (there are a set number of choices and a user can have many choices) as in the example below. I haven't been able to find a good simple example of this (other than how the relationship is laid out). Is this solution viable or is there a better way of doing it? I seem to get the table I'm looking for.
SELECT
users.name,
choices.choice as choice
FROM
choice
JOIN relation ON choice.choice_id = relation.choice_id
JOIN users ON users.name_id = relation.user_id;
Gives me the correct table:
+------+--------+
| name | choice |
+------+--------+
| amy | a |
| amy | b |
| amy | c |
| joe | d |
+------+--------+
The simple database looks like this:
Users
+------+---------+
| name | name_id |
+------+---------+
| amy | 1 |
| joe | 2 |
+------+---------+
Choices
+----------+---------+
| choice_id| choice |
+----------+---------+
| 1 | a |
| 2 | b |
| 3 | c |
| 4 | d |
+----------+---------+
Relation
+----------+---------+
| choice_id| user_id |
+----------+---------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
+----------+---------+

MYSQL issue selecting and sorting from separate tables

I am having difficulty assembling the proper sql statements to list and sort data based upon my needs. Below is the structure of two tables I need to select data from.
For each user in the users table, I need to list id, name, and key[a] and key[b] from users_nfo table.
Table users:
+----+------+
| id | name |
+----+------+
| 1 | aa |
| 2 | bb |
| 3 | cc |
| 4 | dd |
| 5 | ee |
+----+------+
Table users_nfo:
+----+-----+-----+-------+
| id | uid | key | value |
+----+-----+-----+-------+
| 1 | 1 | a | 22 |
| 2 | 1 | b | 47 |
| 3 | 2 | a | 38 |
| 4 | 2 | b | 16 |
| 5 | 3 | a | 27 |
| 6 | 3 | b | 67 |
| 7 | 4 | a | 75 |
| 8 | 4 | b | 67 |
| 9 | 5 | a | 63 |
| 10 | 5 | b | 67 |
+----+-----+-----+-------+
The result should be similar to this
Array result:
+----+------+---+---+
| id | name | a | b |
+----+------+---+---+
| 1 | aa |22 |47 |
| 2 | bb |38 |16 |
| 3 | cc |27 |67 |
| 4 | dd |75 |67 |
| 5 | ee |63 |67 |
+----+------+---+---+
Additionally, I need to be able to sort by any column key, such as sorted asc by b.
Help is appreciated. Thanks in advance!
The trick is to join the users_nfo (sic) table twice, and include the key column in the join condition. Like this:
SELECT u.ID, u.name, n1.value, n2.value from USERS u
JOIN users_nfo n1
ON u.id = n1.id AND n1.key = 'a'
JOIN users_nfo n2
ON u.id = n2.id AND n1.key = 'b'
ORDER BY n2.value ASC