MySQL get first row of joined table in group - mysql

I have a simple one-to-many relationship. One table is a list of albums, and the other a list of photos. Each photo can only be of one album, but an album contains many images.
Now I want to get a list of all the albums in a single query. The information I want is some values of the album itself (let's say the name of the album), the total image count in that album and some values of the first image.
I already have the total image count and the album name, but I am having some issues trying to get the first image values as well.
SELECT albums.id, albums.name, COUNT(photos.id) AS imageCount
FROM albums
LEFT JOIN photos ON albums.id = photos.albumid
GROUP BY name
ORDER BY id DESC
I have tried several approaches from other answers but I seem to be doing something wrong. It's especially confusing since I am using COUNT() as well.
I have created a sqlfiddle that has this query in it as well as a small sample database. So how do I also get some values of the first element of photos?

SELECT x.id
, x.name
, total
, y.id
, y.url
FROM
( SELECT a.*
, COUNT(p.id) total
, MIN(p.id) min_id
FROM albums a
LEFT
JOIN photos p
ON p.albumid = a.id
GROUP
BY a.id
) x
LEFT
JOIN photos y
ON y.id = x.min_id;

you can do by this query:
SELECT albums.id,
albums.name,
COUNT(photos.id) AS imageCount ,
(select url
from photos
where id =(select min(id)
from photos internal_photo
where albums.id = internal_photo.albumid )) as photo_url
FROM albums
LEFT JOIN photos ON albums.id = photos.albumid
GROUP BY name
ORDER BY id DESC

Im using the url format to get the first one, if you have a different format you need another join to get the first one.
SELECT A.*, P.url
FROM
(
SELECT albums.id, albums.name, COUNT(photos.id) AS imageCount
FROM albums
LEFT JOIN photos ON albums.id = photos.albumid
GROUP BY name
) A
LEFT JOIN (
SELECT `albumid`, MIN(`url`) as `url`
FROM photos
GROUP BY `albumid`
) P
ON A.id = P.`albumid`
ORDER BY id DESC
A more generic version free of string hassles would be:
SQL Fiddle Demo
SELECT *
FROM
(
SELECT albums.id, albums.name, COUNT(photos.id) AS imageCount
FROM albums
LEFT JOIN photos ON albums.id = photos.albumid
GROUP BY name
ORDER BY id DESC
) A
LEFT JOIN (
SELECT photos.`albumid`, photos.`url`
FROM photos
LEFT JOIN (
SELECT `albumid`, MIN(`id`) as `id`
FROM photos p1
GROUP BY `albumid`
) P1
ON photos.`albumid` = p1.`albumid`
AND photos.`id` = P1.`id`
) P
ON A.id = P.`albumid`

If you use MySQL as your database, you can run this query
SELECT albums.id, albums.name, photos.url, COUNT(photos.id) AS imageCount
FROM albums
LEFT JOIN photos ON albums.id = photos.albumid
GROUP BY name
ORDER BY id DESC
Because Grouping in MySQL always return the first row value. CMIIW.
But you can also try this query (only a nested subquery).
SELECT albums.id, albums.name, COUNT(photos.id) AS imageCount, (
SELECT photos.url
FROM photos
WHERE albums.id = photos.albumid
ORDER BY id ASC
LIMIT 1
)
FROM albums
LEFT JOIN photos ON albums.id = photos.albumid
GROUP BY name
ORDER BY id DESC

Related

MySQL - Ordering IN within INNER JOIN

I'm creating a system that allows a user to search a database of photo albums images for a keyword, it's working great, the only issue is that I'm ordering relevancy by the amount of times that keyword appears in an album. I'm doing this using:
SELECT collections_ids.collection_id
FROM `keywords`
INNER JOIN collections_ids ON keywords.id = collections_ids.photo_id
WHERE keywords.`keyword` = 'trees'
GROUP BY collection_id
ORDER BY COUNT(*) DESC
As said, this works great.
The only issue is, when this is included in an "WHERE IN" query, it loses it's order and is returned randomly. For clarity, here is the query:
SELECT collections.id,
collections.title
images.img_small
FROM `collections`
INNER JOIN images ON images.id = collections.cover_photo
WHERE collections.`id` IN
(SELECT collections_ids.collection_id
FROM `keywords`
INNER JOIN collections_ids ON keywords.id = collections_ids.photo_id
WHERE keywords.`keyword` = 'trees'
GROUP BY collection_id
ORDER BY COUNT(*) DESC)
I've tried researching, and people have suggested using the FIELD function, but I don't see that working in this context.
Any suggestions?
you can use sub query as join and take it count(*) as order by like below
SELECT collections.id,
collections.title
images.img_small
FROM `collections`
INNER JOIN images ON images.id = collections.cover_photo
INNER JOIN
(SELECT distinct collections_ids.collection_id As collection_id,COUNT(*) as total
FROM `keywords`
INNER JOIN collections_ids ON keywords.id = collections_ids.photo_id
WHERE keywords.`keyword` = 'trees'
GROUP BY collection_id
) as A
ON A.collection_id =collections.collection_id
order by A.total

Joining two columns in mysql

I want to add data from table b in table a but unfortunately full outer join do not work in mysql . I have also tried union but it is throwing errors because my statement has group by and order by keyword
SELECT COUNT( ReviewedBy ) AS TotalReviews, OrganizationId, SUM( Rating ) AS TotalStars, COUNT( Rating ) AS TotalRatings, (
SUM( Rating ) / COUNT( Rating )
) AS AverageRating
FROM `tbl_reviews`
WHERE ReviewType = 'shopper'
AND ReviewFor = 'org'
AND OrganizationId
IN (
SELECT OrganizationId
FROM tbl_organizations
WHERE CategoryID =79
)
GROUP BY OrganizationId
ORDER BY AverageRating DESC
This is what i'm getting from the above statement
I want to get organizationId 21 data in the result but i'm not getting result because it's not present in 'tbl_review' table
click here to see the table b
How can i get Desired result ?
You don't need a FULL, but a LEFT join:
SELECT COUNT( ReviewedBy ) AS TotalReviews, o.OrganizationId,
SUM( Rating ) AS TotalStars, COUNT( Rating ) AS TotalRatings,
(SUM( Rating ) / COUNT( Rating )) AS AverageRating
FROM tbl_organizations AS o
LEFT JOIN `tbl_reviews` AS r
ON o.OrganizationId = r.OrganizationId
AND ReviewType = 'shopper' -- conditions on inner table
AND ReviewFor = 'org' -- must be moved to ON
WHERE CategoryID =79
GROUP BY o.OrganizationId
ORDER BY AverageRating DESC
Why don't you use AVG instead of SUM/COUNT?
Have you tried:
from organization
left outer join tbl_reviews
on organization.ID = tbl_reviews.organization is
for your where clause? I don't think you need a full outer join in this case... A left outer join should do

mysql: getting getting tuple of an alias which has maximum column value

What I want to do is this:
select AlbumId from (
select Album.AlbumId, Sum(Track.UnitPrice) as Total from Album
inner join Track on Album.AlbumId = Track.AlbumId
group by Album.AlbumId
) tpt
where Total = (select max(Total) from tpt);
but am getting:
Table 'db.tpt' doesn't exist
-which probably makes sense. However, I am new to SQL and don't know why tpt goes out of scope in my where clause. How can I achieve this? I want to get the tuple with the Max total and extract the AlbumId.
Thanks!
Use a JOIN with subqueries.
select tpt.AlbumId from (
select Album.AlbumId, Sum(Track.UnitPrice) as Total from Album
inner join Track on Album.AlbumId = Track.AlbumId
group by Album.AlbumId
) tpt
JOIN (
select Sum(Track.UnitPrice) as Total from Album
inner join Track on Album.AlbumId = Track.AlbumId
group by Album.AlbumId
ORDER BY Total DESC
LIMIT 1
) maxtpt ON tpt.Total = maxtpt.Total

can we have a query of "10 posts from every category in one request"?

We have a list of posts that belong a category.
can we have a query of "10 posts from every category in one request" ?
Or
We have to query 10 posts for every category separately ?
thx
A fudge involving using GROUP_CONCAT to put all the post ids for a category together (you can add an order clause to this if you want), then substring_index to get the first 10 posts.
This is then joined back to the original table using FIND_IN_SET
SELECT a.*
FROM some_table a
INNER JOIN
(
SELECT category_id, SUBSTRING_INDEX(GROUP_CONCAT(post_id), ',', 10) AS posts
FROM some_table
GROUP BY catgegory_id
) sub0
ON a.category_id = sub0.category_id
AND FIND_IN_SET(a.post_id, sub0.posts)
Or using variables:-
SELECT a.*
FROM some_table a
INNER JOIN
(
SELECT category_id, post_id, #cnt:=IF(#category_id=category_id, #cnt + 1, 1) AS cnt, #category_id:=category_id
FROM
(
SELECT category_id, post_id
FROM some_table
ORDER BY category_id, post_id
) sub0
CROSS JOIN (SELECT #cnt:=0, #category_id:=0) sub1
) sub2
ON a.category_id = sub2.category_id
AND a.post_id = sub2.post_id
AND cnt <= 10
This pseudo code should point you in the right direction.
SELECT DISTINCT CATEGORY FROM T AS T1
CROSS JOIN (SELECT * FROM T WHERE T.CATEGORY = T1.CATEGORY ORDER BY CATEGORY DESC LIMIT 10)

count from another table with inner

i want to get the number of occures in another Table in MySQL.
My current Query looks like following:
SELECT
teilnehmer.`name`,
teilnehmer.`status`
FROM
teilnehmer
INNER JOIN chat ON chat.cid = teilnehmer.id
INNER JOIN videos ON videos.tid = teilnehmer.id
GROUP BY
chat.id,
videos.tid
I want now the amount of teilnehmer.id's in chat.cid's and the amount of teilehmer.id's in videos.tid's
How can i do that?
Seems like you want this:
SELECT teilnehmer.`name`,
teilnehmer.`status`,
c.ChatCount,
v.VideoCount
FROM teilnehmer
INNER JOIN
(
select count(cid) ChatCount, cid
from chat
group by cid
) c
ON c.cid = teilnehmer.id
INNER JOIN
(
select count(tid) VideoCount, tid
from videos
group by tid
) v
ON v.tid = teilnehmer.id