I've these 2 tables in MySQL:
Table ___Photos:
|--------|-----------|-------------|
| AMP_Id | AMP_Photo | AMP_Formats |
|--------|-----------|-------------|
| 1 | dog.jpg | 1,2 |
| 1 | cat.jpg | 3 |
|--------|-----------|-------------|
Table ___Formats:
|--------|------------|
| AMF_Id | AMF_Format |
|--------|------------|
| 1 | 10x10 |
| 2 | 30x30 |
| 3 | 40x40 |
|--------|------------|
How can I list each Photos with the formats linked in ___Formats ?
For example, for the tables show above, I would need something like this:
|-----------|-------------|
| AMP_Photo | AMF_Format |
|-----------|-------------|
| dog.jpg | 10x10,30x30 |
| cat.jpg | 40x40 |
|-----------|-------------|
This is what I have tried so far:
SELECT
AMP_Photo,
IFNULL(GROUP_CONCAT(AMF_Format), "") as list_formats
FROM ___Photos i
LEFT JOIN ___Formats f
ON f.AMF_Id = AMF_Format
GROUP BY AMP_Photo
ORDER BY AMP_Photo ASC
You can do it as follows using concat :
SELECT
AMP_Photo,
IFNULL(GROUP_CONCAT(AMF_Format), "") as list_formats
FROM ___Photos i
INNER JOIN ___Formats f ON i.AMP_Formats like concat('%',f.AMF_Id,'%')
GROUP BY AMP_Photo
ORDER BY AMP_Photo ASC
demo here : https://dbfiddle.uk/eiQIgI8f
Related
so what I am trying to do is having 3 tables (pictures, collections, and bridge) with the following columns:
Collections Table:
| id | name |
------------------
| 1 | coll1 |
| 2 | coll2 |
------------------
Pictures Table: (timestamps are unix timestamps)
| id | name | timestamp |
-------------------------
| 5 | Pic5 | 1 |
| 6 | Pic6 | 19 |
| 7 | Pic7 | 3 |
| 8 | Pic8 | 892 |
| 9 | Pic9 | 4 |
-------------------------
Bridge Table:
| id | collection | picture |
-----------------------------
| 1 | 1 | 5 |
| 2 | 1 | 6 |
| 3 | 1 | 7 |
| 4 | 1 | 8 |
| 5 | 2 | 5 |
| 6 | 2 | 9 |
| 7 | 2 | 7 |
-----------------------------
And the result should look like this:
| collection_name | picture_count | newest_picture |
----------------------------------------------------
| coll1 | 4 | 8 |
| coll2 | 3 | 9 |
----------------------------------------------------
newest_picture should always be the picture with the heighest timestamp in that collection and I also want to sort the result by it. picture_count is obviously the count of picture in that collection.
Can this be done in a single statement with table joins and if yes:
how can I do this the best way?
A simple method uses correlated subqueries:
select c.*,
(select count(*)
from bridge b
where b.collection = c.id
) as pic_count,
(select p.id
from bridge b join
pictures p
on b.picture = b.id
where b.collection = c.id
order by p.timestamp desc
limit 1
) as most_recent_picture
from collections c;
A more common approach would use window functions:
select c.id, c.name, count(bp.collection), bp.most_recent_picture
from collections c left join
(select b.*,
first_value(p.id) over (partition by b.collection order by p.timestamp desc) as most_recent_picture
from bridge b join
pictures p
on b.picture = p.id
) bp
on bp.collection = c.id
group by c.id, c.name, bp.most_recent_picture;
table 1: forum_threads
+-----+------+-------+
| id | title| status|
+-----+------+-------+
| 1 | a | 1 |
| 2 | b | 1 |
| 3 | c | 1 |
| 4 | d | 1 |
| 5 | e | 1 |
| 6 | f | 1 |
+-----+------+-------+
table 2: forum_comments
+-----+----------+--------------------+
| id | thread_id| comment |
+-----+----------+--------------------+
| 1 | 4 | hai |
| 2 | 4 | hello |
| 3 | 2 | welcome |
| 4 | 2 | whats your name |
| 5 | 6 | how are you |
| 6 | 5 | how old are you |
| 7 | 5 | good |
+-----+----------+--------------------+
wanted output
+-----------+----------+-----------------+
| thread_id | title | comment_count |
+-----------+----------+-----------------+
| 5 | e | 2 |
| 6 | f | 1 |
| 2 | b | 2 |
| 4 | d | 2 |
+-----------+----------+-----------------+
my Query
SELECT forum_threads.*,forum_comments.*,count(forum_comments.id) as comment_count
FROM forum_comments
LEFT JOIN forum_threads ON forum_comments.thread_id = forum_threads.id
GROUP BY forum_threads.id
ORDER BY forum_comments.id desc
Here I am trying to get the titles by the latest comment.
when I give ORDER BY forum_comments.id this returns the wrong order.
I need to order by the latest comments in the forum_comments table.
this query returns the wrong order please help me to find out the correct order.
how could I solve this easily?
This query should give you the expected result:
select t2.thread_id, t1.title, t2.comment_count from forum_threads as t1,
(SELECT id, thread_id, count(comment) as comment_count from forum_comments group by thread_id) as t2
where t1.id = t2.thread_id order by t2.id desc;
Instead of using forum_threads.* and forum_comments.* can you give specific column names and try.
If that doesn't work you should try explicitly assigning primary and foreign keys.
Got following Tables in my SQL-Database (simplified):
Table Blogs:
+----+----------------------+----------+
| ID | Date | TitleGer |
+----+----------------------+----------+
| 1 | 2017-04-28 15:09:46 | Huhu |
| 2 | 2017-04-28 15:16:18 | Miau |
| 3 | 2017-04-28 15:17:14 | Kleff |
+----+----------------------+----------+
Table PicturesJoin:
+-------------+---------+---------------------+
| IDPicture | IDBlog | Date |
+-------------+---------+---------------------+
| 86 | 1 | 2017-06-28 17:41:11 |
| 87 | 1 | 2017-06-28 17:41:11 |
+-------------+---------+---------------------+
Table Pictures:
+------+-------------------------+---------------------+
| ID | Filename | Date |
+------+-------------------------+---------------------+
| 86 | 20170512200326_320.jpg | 2017-05-12 20:03:26 |
| 87 | 20170512200326_384.jpg | 2017-05-12 20:03:30 |
+------+-------------------------+---------------------+
PictureJoin "joins" the Picture with the Blog-Table. Now I use following SQL-Command to joine these two Tables (Blog - PictureJoin) / (PictureJoin - Pictures) together.
SELECT
Blogs.ID,
Blogs.Date,
TitleGer,
Pictures.Filename
FROM
Blogs
LEFT JOIN
PicturesJoin ON PicturesJoin.IDBlog = Blogs.ID
LEFT JOIN
Pictures ON Pictures.ID = PicturesJoin.IDPicture
ORDER BY
DATE DESC
The result might look like that:
+------+----------------------+-----------+------------------------+
| ID | Date | TitleGer | Filename |
+------+----------------------+-----------+------------------------+
| 1 | 2017-06-28 15:09:46 | Huhu | 20170512200326_320.jpg |
| 1 | 2017-06-28 15:09:46 | Huhu | 20170512200326_384.jpg |
| 2 | 2017-04-28 15:16:18 | Miau | NULL |
| 3 | 2017-04-28 15:17:14 | Kleff | NULL |
+------+----------------------+-----------+------------------------+
He makes a cross-product out of the available Pictures, which is also logical. But I want him to just use the first Picture he finds. In the end it should look like that:
+------+----------------------+-----------+------------------------+
| ID | Date | TitleGer | Filename |
+------+----------------------+-----------+------------------------+
| 1 | 2017-06-28 15:09:46 | Huhu | 20170512200326_320.jpg |
| 2 | 2017-04-28 15:16:18 | Miau | NULL |
| 3 | 2017-04-28 15:17:14 | Kleff | NULL |
+------+----------------------+-----------+------------------------+
Tried several hours but couldn't get it to work. Please help!
The easiest approach may be to select one IDPicture per IDBlog from PicturesJoin only:
SELECT
b.ID,
b.Date,
b.TitleGer,
p.Filename
FROM Blogs b
LEFT JOIN
(
SELECT
IDBlog,
MIN(IDPicture) AS IDPicture
FROM PicturesJoin
GROUP BY IDBlog
) pj ON pj.IDBlog = b.ID
LEFT JOIN Pictures p ON p.ID = pj.IDPicture
ORDER BY b.Date DESC;
SELECT b.ID,b.Date,b.TitleGer,p.Filename
FROM Blogs b
LEFT JOIN
(
SELECT main_table.*
FROM PicturesJoin main_table LEFT JOIN PicturesJoin child_table
ON (main_table.IDBlog= child_table.IDBlog AND main_table.IDPicture> child_table.IDPicture)
WHERE child_table.id IS NULL
)
OUTER_TABLE ON OUTER_TABLE .IDBlog = b.ID
LEFT JOIN Pictures p ON p.ID = pj.IDPicture
ORDER BY b.Date DESC;
Try above query.
I'm using MariaDB 5.5, but for this solution it would be same as for MySQL. I have two tables, first one contains galleries and second one contains info about files within each gallery. This is example of the table gallery:
+----+-------+-----+
| id | name | ... |
+----+-------+-----+
| 1 | test1 | ... |
| 2 | test2 | ... |
| 3 | test3 | ... |
| 4 | test4 | ... |
+----+-------+-----+
This is example of the table gallery_items:
+----+------+------------+-----+
| id | file | gallery_id | ... |
+----+------+------------+-----+
| 1 | img1 | 3 | ... |
| 2 | img2 | 2 | ... |
| 3 | img3 | 2 | ... |
| 4 | img4 | 1 | ... |
+----+------+------------+-----+
So I tried this code:
SELECT gallery.*, COUNT(gallery_items.id) AS items FROM gallery JOIN gallery_items WHERE gallery_items.gallery_id = gallery.id;
Well, I'm not really good with databases, so this is why I'm asking for help. This is my expected result:
+----+-------+-------+-----+
| id | name | items | ... |
+----+-------+-------+-----+
| 1 | test1 | 1 | ... |
| 2 | test2 | 2 | ... |
| 3 | test3 | 1 | ... |
| 4 | test4 | 0 | ... |
+----+-------+-------+-----+
you will need to GROUP BY in order for a COUNT to work
SELECT gallery.*, COUNT(gallery_items.id) AS items FROM gallery
LEFT JOIN gallery_items ON gallery_items.gallery_id = gallery.id
GROUP BY gallery.id, gallery.name
Description You may use the following query
SELECT
g.*,COUNT(gi.id) AS items
FROM
gallery g
LEFT JOIN gallery_items gi
ON g.id = gi.gallery_id
GROUP BY g.id;
How do I solve this one? None of my queries works and I've tried few.
I've got to return details of two doctors who ordered the most analysis including the number of analysis they have ordered. That last part of the sentence is what really drives me mad.
To work with I've got these two tables:
mysql> select * from DOCTORES;
+-----------+---------------------------+--------------+-----------+
| DNI_DOC | NOMBRE_DOC | ESPECIALIDAD | TELEFONO |
+-----------+---------------------------+--------------+-----------+
| 22888444O | MATEO DÍAZ, RAMÓN | 3 | 659876457 |
| 22909456Y | HERAS PRADO, ANTONIA | 1 | 676234598 |
| 23456398F | GÓMEZ DAVID, ADRIÁN | 1 | 646768454 |
| 25349857H | BURGOS CASA, CANDY | 2 | 659758476 |
| 55776898K | RAMÓN CORONADO,LUIS | 3 | 654364736 |
| 78988484B | CONRADO ALONSO, JOSE | 2 | 645878745 |
| 88647389P | DOMÍNGUEZ GÓMEZ, MANUEL | 1 | 623787343 |
+-----------+---------------------------+--------------+-----------+
and:
mysql> select * from PETICIONES;
+--------+------------+--------+-----------+-----------+
| ID_PET | FECHA_PET | ID_ANA | DNI_PAC | DNI_DOC |
+--------+------------+--------+-----------+-----------+
| 1 | 2008-01-03 | 2 | 71515623A | 23456398F |
| 2 | 2008-05-10 | 2 | 33788976F | 55776898K |
| 3 | 2008-05-08 | 3 | 79876867X | 23456398F |
| 4 | 2008-05-11 | 4 | 44787345H | 55776898K |
| 5 | 2008-05-12 | 2 | 19887234W | 25349857H |
| 6 | 2008-05-05 | 4 | 22897576R | 55776898K |
| 7 | 2008-03-15 | 5 | 44787345H | 88647389P |
| 8 | 2008-03-19 | 1 | 71515623A | 23456398F |
| 9 | 2008-03-26 | 2 | 71515623A | 78988484B |
| 10 | 2008-03-15 | 2 | 19887234W | 88647389P |
| 11 | 2008-03-15 | 3 | 33788976F | 55776898K |
| 12 | 2008-03-26 | 2 | 44787345H | 23456398F |
+--------+------------+--------+-----------+-----------+
I tried this:
select
NOMBRE_DOC
from
DOCTORES
where
DNI_DOC IN (select DNI_DOC
from PETICIONES
group by ID_ANA
order by count(*) desc
limit 2)
group by
DNI_DOC;
and that:
SELECT
DNI_DOC, ID_ANA, COUNT(ID_ANA) AS count
FROM
TIPOS_ANALISIS
WHERE
ID_ANA = (SELECT ID_ANA
FROM
(SELECT
ID_ANA, COUNT(ID_ANA) as AnaCount
FROM
PETICIONES
GROUP BY
by ID_ANA
ORDER BY
AnaCount DESC
LIMIT 1) t1)
GROUP
BY ID_ANA;
and that:
select a.* from DOCTORES a
-> where a.DNI_DOC = ( SELECT b.DNI_DOC from PETICIONES b
-> group by d.ID_ANA
-> order by count(ID_ANA) DESC
-> limit 2 );
you can't even imagine how frustrating it is when you say it's a simple query... Why it isn't simple to me is a mystery (provided that I am really not a dummy).
Expected output would be something like this:
+-----------+---------------------------+--------------+-----------+
| DNI_DOC | NOMBRE_DOC | ID_ANA | count |
+-----------+---------------------------+--------------+-----------+
| 22888444O | MATEO DÍAZ, RAMÓN | 3 | 6 |
+-----------+---------------------------+--------------+-----------+
I believe you are severely overcomplicating this. Join the 2 tables on DNI_DOC field, group by the doctor's id and name (and any other details you may want to include in the select list), and count the number of distinct ID_ANAs.
SELECT d.DNI_DOC, d.NOMBRE_DOC, COUNT(distinct ID_ANA) AS count
FROM DOCTORES d
INNER JOIN PETICIONES t ON d.DNI_DOC=t.DNI_DOC
GROUP BY d.DNI_DOC, d.NOMBRE_DOC
ORDER BY COUNT(distinct ID_ANA) DESC
LIMIT 2
If you need the total number of peticiones per doctor, then remove the distinct from the count.
Here is what I would do :
select d.*, count(p.ID_PET) as TOTAL_PETICIONES from DOCTORES d
inner join PETICIONES p on p.DNI_DOC = d.DNI_DOC
group by d.DNI_DOC
order by count(ID_ANA) DESC
limit 2
This is not tested and write here so please correct me for typos ;)
Using a join will provide a nice output. Grouping by DOCTORES to be able to count the PETICIONES per DOCtORES
EDIT : Something like that. The output won't be good because I have issues to understand the column content.