MySQL innerjoin on an array_field - mysql

I have two tables
[series]
--------------
ID | ART
--------------
1 | sculptor
2 | painter
3 | writer
--------------
[artists]
--------------
NAME | ART_IDs
--------------
john | 1
jack | 1,2
jill | 2,1
jeff | 3,1
which I want to join like this:
SELECT se.art, ar.name as artist
FROM series AS se
INNER JOIN artists AS ar ON (se.id IN (ar.art_ids))
What I get is only the first values:
[result]
-------------------
ART | ARTISTS
-------------------
sculptor | john
sculptor | jack
painter | jill
writer | jeff
Instead of:
[result]
-------------------
ART | ARTISTS
-------------------
sculptor | john
sculptor | jack
sculptor | jill
sculptor | jeff
painter | jack
painter | jill
writer | jeff
Normally I would do this with a third table with the links pe.id<->se.id. But another table is quite complicated to maintain in my framework.

As mentioned above the best option is to fix your table structure, its best to do it now while you have the chance. As the data grows it will start causing a lot of headaches. However if you know what you are doing, i think this will get you what you want in the short term:
SELECT se.art, ar.name as artist
FROM series AS se
JOIN artists AS ar ON FIND_IN_SET(se.id , ar.art_ids) > 0

Related

How to select a column's value, only if all other entries with the same value exist and match? (MYSQL)

The title is a bit messy, but here's an example
suppose we have table:
| name | room |
=================
| John | 4 |
| John | 6 |
| John | 9 |
| Smith | 4 |
| Smith | 6 |
| Brian | 4 |
| Brian | 6 |
| Brian | 9 |
I want to select John and Brian because they both have exactly rooms 4, 6 and 9, but not Smith, since he doesn't have the room 9. (If we had another person who ONLY has room 4 and 6, then it'd select that other person as well as Smith).
I know I need to do some kind of correlated query, but I'm not sure how to actually get it to do something like
for a check for b
If you want groups of names that share the exact same rooms, I would recommend group_concat():
select rooms, group_concat(name) as names
from (select name, group_concat(room order by room) as rooms
from t
group by name
) n
group by rooms;
If you want only combinations with more than one name, then add having count(*) > 1 to the outer select.

How to count unique items in column in Access

I need help. I can't seem to find the logic behind this code.
I am working on a voting system, and I need to output the results of the votes.
I want to count all of the rows that has a unique name in it and output how many.
My table goes like this.
voterid | pres | vpres | sec | trea | PIO
---------------------------------------------
1 | John | Mitch | James | Jack | Eman
2 | John | Pao | Bryan | Jack | Faye
3 | Kelvin | Pao | James | Jeck | Faye
Output should be
Pres | Votes
--------------
John | 2
Kelvin | 1
Here's my code.
SELECT DISTINCT
pres,
(SELECT COUNT(pres) FROM (SELECT DISTINCT pres FROM tblVote AS Votes)) AS Votes
FROM tblVote
Thanks in advance!
I think you are just looking for a simple GROUP BY query:
SELECT pres, COUNT(*) AS Votes
FROM tblVote
GROUP BY pres

MySQL innerjoin on an array field

i have 2 tables
[series]
--------------
ID | ART
--------------
1 | sculptor
2 | painter
3 | writer
-----------
[artists]
--------------
NAME | ART_IDs
--------------
john | 1
jack | 1,2
jill | 2,1
jeff | 3,1
which I want to join like this:
SELECT se.art, ar.name as artist
FROM series AS se
JOIN artists AS ar ON FIND_IN_SET(se.id , ar.art_ids) > 0
What I get is only the first values:
[result]
-------------------
ART | ARTISTS
-------------------
sculptor | john
sculptor | jack
painter | jill
writer | jeff
Instead of:
[result]
----------------------------
ART | ARTISTS
----------------------------
sculptor | john
sculptor,painter | jack
painter,sculptor | jill
writer,sculptor | jeff
Try this:
SELECT GROUP_CONCAT(se.art ORDER BY FIND_IN_SET(se.id , ar.art_ids)) as art, ar.name as artist
FROM series AS se
JOIN artists AS ar ON FIND_IN_SET(se.id , ar.art_ids) > 0
GROUP BY ar.name
If you want to concat column in each group, GROUP_CONCAT can help you.
Check demo in Rextester.

Single MySQL query on three tables

I have three tables as below:
Table 1: player_game
player_id | game_id
-------------------
1 | 1
2 | 2
5 | 20
4 | 1
2 | 20
-------------------
Table 2: players
player_id | player_name | player_age
------------------------------------
1 | John | 20
2 | Abe | 18
5 | Lisa | 21
4 | Mary | 25
3 | Romeo | 21
------------------------------------
Table 3: games
game_id | game_name | diff_level
------------------------------------
1 | AOE | easy
2 | Contra | easy
11 | Tribalwars | difficult
20 | Tanks | novice
25 | Minesweeper | medium
------------------------------------
I want to write a query that looks up the players and games table by using the IDs on the player_game table. The resulting table should give the player name and the corresponding games name. All the names of the players should be returned. If any player does not have an ID in the player_game table, it should list a NULL. Expected output is below:
Result:
Player Name | Games Name
--------------------------
John | AOE
Abe | Contra
Lisa | Tanks
Mary | AOE
Romeo | NULL
Abe | Tanks
--------------------------
I have written the following query but its not working:
SELECT p.player_name AS "Player Name", g.game_name AS "Games Name"
FROM players p
LEFT OUTER JOIN player_game pg
ON p.player_id = pg.player_id
JOIN games g
ON g.game_id = pg.game_id;
Please advise what am I doing wrong.
Your answer looks good except your 2nd join. Your 2nd join should also be left(outer) join otherwise you won't be seeing "Romeo NULL" record.
Other than this, Abe has 2 games linked( Contra and Tanks) as it is already mentioned. You expect to see both of them in your output? If so, your code will do it. If you want Abe to have only one game linked, then you need to tell us the logic for selecting the one of the games.

Use MySQL to create a string out of a subquery?

What I'm hoping to do is create a string out of a table WITHIN a query so that I may be able to place that string in another query I'm creating. Say, I have this for a table:
index | position | name
----------------------------------------
1 | member | John Smith
2 | chair | Mary Jones
3 | member | Mary Jones
4 | contact | Grace Adams
5 | director | Grace Adams
6 | member | Grace Adams
7 | treasurer | Bill McDonnell
8 | vice chair | Bill McDonnell
9 | member | Ishmael Rodriguez
I'm looking for the result as follows:
name | positions
----------------------------------------
John Smith | member
Mary Jones | chair,member
Grace Adams | contact,director,member
Bill McDonnell | treasurer,vice chair
Ishmael Rodriguez | member
I was hoping I could use some variant of CONCAT_WS() to get my result, like this...
SELECT
a.NAME,
CONCAT_WS(
',',
(
SELECT
position
FROM
TABLE
WHERE
NAME = a.NAME
)
)AS positions FROM ---------------
Obviously, this isn't working out for me. Any ideas?
Use GROUP_CONCAT[docs]
SELECT name, GROUP_CONCAT(position) result
FROM tableName
GROUP BY name
ORDER BY `index`
SQLFiddle Demo
Use GROUP_CONCAT like so:
SELECT name, GROUP_CONCAT(position SEPARATOR ',')
FROM Table
GROUP BY name