Separated List with id's of related columns - mysql

Let's assume the following table:
| id | firstname | secondname | group |
|:-----------|------------:|:------------:|:------------:|
| 1 | Tom | Test1 | 111 |
| 2 | Jack | Test2 | 222 |
| 3 | Chris | Test3 | 333 |
| 4 | Lucy | Test4 | 333 |
| 5 | Joe | Test5 | 111 |
| 6 | John | Test6 | 111 |
how can i get a Query with the information, which others are in the same group?
I want to get something like this:
| id | firstname | secondname | group | others |
|:-----------|------------:|:------------:|:------------:|:------------:|
| 1 | Tom | Test1 | 111 | 5,6 |
| 2 | Jack | Test2 | 222 | |
| 3 | Chris | Test3 | 333 | 4 |
| 4 | Lucy | Test4 | 333 | 3 |
| 5 | Joe | Test5 | 111 | 1,6 |
| 6 | John | Test6 | 111 | 1,5 |
it would also be ok, if the separated list also includes the related id itself.
i tried this one, but i got only one row with all ids in the "others"-column
Select A.id,A.firstname,A.secondname,A.group,GROUP_CONCAT(B.id) from myTable A
inner join myTable B
on (A.group = B.group)
where a.id <> b.id

You can use a correlated subquery:
select a.*,
(select group_concat(b.id)
from mytable b
where b.group = a.group and b.id <> a.id
) as OthersInGroup
from myTable a;
Note: group is a keyword and a reserved word in MySQL, so I hope that is not the real name of the column.
A correlated subquery seems simpler than a left join and aggregation. With an index on mytable(group, id) it should have pretty good performance too.

Related

Multiple tables JOIN with WHERE clause including rows that haven't common id

I suppose this topic has been discussed already here. However I couldn't find something useful for my issue, so links are welcomed.
There are three tables. Table test2 have two foreign keys for tables test1 and test3.
test1 test2 test3
+----+------+ +----+-------+-------+----+ +----+------------+
| id | name | | id | t1_id | t3_id | v2 | | id | co_date |
+----+------+ +----+-------+-------+----+ +----+------------+
| 1 | A | | 1 | 3 | 1 | 15 | | 1 | 2018-12-02 |
| 2 | B | | 2 | 4 | 1 | 20 | | 2 | 2019-02-03 |
| 3 | C | | 3 | 9 | 2 | 35 | | 3 | 2019-03-04 |
| 4 | D | | 4 | 5 | 3 | 12 | | 4 | 2019-04-05 |
| 5 | E | | 5 | 6 | 3 | 12 | | 5 | 2019-09-01 |
| 6 | F | | 6 | 9 | 4 | 20 | | 6 | 2019-10-02 |
| 7 | G | | 7 | 6 | 5 | 10 | | 7 | 2019-11-03 |
| 8 | H | | 8 | 7 | 5 | 10 | | 8 | 2019-12-04 |
| 9 | I | | ....................... | | 9 | 2020-02-05 |
| 10 | J | | 20 | 4 | 10 | 30 | | 10 | 2020-03-06 |
+----+------+ +----+-------+-------+----+ +----+------------+
I want to sum all v2 values from test2 by names within certain period. The problem is that some names are not presented in that period. And they are excluded from query result.
I've tried to use LEFT-hand join, but it doesn't work that way.
SELECT t1.name, SUM(v2) FROM test1 as t1
LEFT OUTER JOIN test2 as t2
ON t1.id = t2.t1_id
LEFT OUTER JOIN test3 as t3
ON t2.t3_id = t3.id
WHERE co_date BETWEEN '2019-01-01' AND '2019-12-31'
GROUP BY name
ORDER BY name
The following result doesn't include 'A' to 'D' names.
+------+---------+
| name | SUM(v2) |
+------+---------+
| E | 26 |
| F | 37 |
| G | 35 |
| H | 10 |
| I | 90 |
| J | 20 |
+------+---------+
But I expected that they should be with NULL in other fields. Isn't this the way how LEFT JOIN works: all rows from left table and intersections with other tables?
Also, I have tried Cartesian product, but I don't know how to group it correctly.
Here's the demo.
I will appreciate any advice about how should I think here.
You need to include the date filters in the ON clause:
SELECT t1.name, SUM(v2)
FROM test1 t1 LEFT JOIN
test2 t2
ON t1.id = t2.t1_id LEFT JOIN
test3 t3
ON t2.t3_id = t3.id AND
t3.co_date BETWEEN '2019-01-01' AND '2019-12-31'
GROUP BY t1.name
ORDER BY name;
The WHERE clause turns the outer join into an inner join -- which is why you lose rows. It does so because NULL fails the comparison in the WHERE clause filtering the "outer joined" results.

mysql unable to display repeated entries in the view

I have the following table in the maria database
i am looking for the following output as a view
I have tried different approaches but it is not working.
Use group_concat() to aggregate the ids and do a self join of the table:
select t.id, t.name,
group_concat(tt.id order by tt.id) repeated
from tablename t left join tablename tt
on tt.name = t.name and tt.id <> t.id
group by t.id, t.name
order by t.id
See the demo.
Results:
| id | name | repeated |
| --- | ----- | -------- |
| 1 | John | 4,8 |
| 2 | Smith | 3 |
| 3 | Smith | 2 |
| 4 | John | 1,8 |
| 5 | Anna | |
| 6 | David | 7 |
| 7 | David | 6 |
| 8 | John | 1,4 |

Get MAX value rows from second table on join

I have 2 tables, first one keeps names and second is related to it on in = cid. I need to get only the highest date row from second table, once. Please look below for clearer explanation:
table1 a
+----+-------+
| id | name |
+----+-------+
| 1 | name1 |
| 2 | name2 |
| 3 | name3 |
| 4 | name4 |
| 5 | name5 |
+----+-------+
table2 c
+----+-------+------------+
| id | cid | galiojaiki |
+----+-------+------------+
| 1 | 1 | 2015-04-30 |
| 2 | 1 | 2015-09-30 |
| 3 | 1 | 2015-03-10 |
| 4 | 2 | 2015-06-30 |
| 5 | 2 | 2015-07-30 |
| 6 | 3 | 2015-05-11 |
| 7 | 4 | 2015-05-10 |
+----+-------+------------+
Expected result:
+------------+-------+
| galiojaiki | name |
+------------+-------+
| 2015-09-30 | name1 |
| 2015-07-30 | name2 |
| 2015-05-11 | name3 |
| 2015-05-11 | name4 |
+------------+-------+
My query:
SELECT a.*, c.galiojaiki FROM `y6fdt_igym_abonementai` AS a
INNER JOIN
(
SELECT max(galiojaiki) FROM y6fdt_igym_sutartys
) c
on c.cid= a.id
GROUP BY c.abonementas
How anout a simple aggregation using MAX?
Something like
SELECT a.name,
MAX(b.galiojaiki) as galiojaiki
FROM `y6fdt_igym_abonementai` AS a INNER JOIN
`y6fdt_igym_sutartys` as b ON a.ID = b.CID
GROUP BY a.name
SQL Fiddle DEMO

Select a table and join 2 different tables

I have 3 table, book table is primary table, female and male are secondary, I need join second and third by first by conditional.
example book:
+------+---------+----------+
| b_id | b_title | b_author |
+------+---------+----------+
| 1 | First | 3 |
| 2 | Second | 1 |
| 3 | Third | -4 |
| 4 | test | -3 |
+------+---------+----------+
male:
+------+--------+
| m_id | m_name |
+------+--------+
| 1 | John |
| 2 | Jim |
| 3 | Jessy |
| 4 | Mike |
| 5 | Tom |
+------+--------+
female:
+------+--------+
| f_id | f_name |
+------+--------+
| 1 | Sarah |
| 2 | Shanon |
| 3 | Nina |
| 4 | Shina |
| 5 | Mary |
+------+--------+
Now I need select from book and when the b_author is positive select from male table and where the b_author select from female table.
SELECT b_id,b_title, IF(b_author > 0,m_name,f_name) AS 'b_author' FROM book -- how make join here.
select *
from book b
left join male m on m.m_id=b.b_author
left join female f on f.f_id=b.b_author*-1

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