Joining two columns in mysql - 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

Related

Multiple inner-join statements combined with subquery

Following query shows the results I need from table pointsList (latest records per user grouped by column idMatch)
select * from pointsList p
inner join ( select idMatch, max(datePointsCalculated ) as MaxDate from pointsList group by idMatch ) tm
on p.idMatch = tm.idMatch and p.datePointsCalculated = tm.MaxDate
order by p.idMatch ASC
But now I want to also select some additional information about the user (from table users). My naive way to tackle this was by making a new inner join like this:
select * from pointsList p, users u
inner join users
on u.idUser = p.idUser
inner join ( select idMatch, max(datePointsCalculated ) as MaxDate from pointsList group by idMatch ) tm
on p.idMatch = tm.idMatch and p.datePointsCalculated = tm.MaxDate
order by p.idMatch ASC
But I get the error message "unknown column 'p.idUser' in on clause". I tried using users.idUser and pointsList.idUser and other combinations (renaming pointsList in the on-clouse) but I always get the unknown column error (pointsList.idUser really does exist). Anyone could explain what I am doing wrong? I would like to extend this query to another table as well.
Thank you in advance!
Comma , priority in FROM clause is less than JOIN priority. And your query acts as:
select * from pointsList p,
(
users u
inner join users
on u.idUser = p.idUser
inner join ( select idMatch, max(datePointsCalculated ) as MaxDate from pointsList group by idMatch ) tm
on p.idMatch = tm.idMatch and p.datePointsCalculated = tm.MaxDate
)
order by p.idMatch ASC
Of course, table pointsList AS p is not accessible within the parenthesis.
Use CROSS JOIN instead of comma:
select * from pointsList p
CROSS JOIN users u
inner join users
on u.idUser = p.idUser
inner join ( select idMatch, max(datePointsCalculated ) as MaxDate from pointsList group by idMatch ) tm
on p.idMatch = tm.idMatch and p.datePointsCalculated = tm.MaxDate
order by p.idMatch ASC

mysql count table rows with count child tables rows

I have three tables. a>b>c tables. I want to totals separately each other and optimize query. My query is not giving the true counts.
TABLE: a
a
-----------
id
no
create_time
TABLE: b
b
-----------
id
no
TABLE: c
c
-----------
id
b_id
this query is not giving the true counts
SELECT
DATE( a.create_time ) AS date,
COUNT( a.id ) AS total_a,
COUNT( b.id ) AS total_b,
COUNT( c.id ) AS total_c
FROM
`a`
LEFT JOIN `b` ON `a`.`no` = `b`.`no`
LEFT JOIN `c` ON `b`.`id` = `c`.`b_id`
WHERE
( `a`.`status` = 1 )
GROUP BY
DATE( a.create_time )
ORDER BY
`date` DESC
LIMIT 20
A left join repeats each row on the left hand side for each matching row on the right hand side. So you get more rows than in the original.
An easy fix is to count just the unique identifiers:
SELECT
DATE( a.create_time ) AS date,
COUNT( DISTINCT a.id ) AS total_a,
COUNT( DISTINCT b.id ) AS total_b,
COUNT( DISTINCT c.id ) AS total_c

MySQL get first row of joined table in group

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

SQL Query with Joins Counting multiple Results Per Record Ordering By Count

I have a table called Request.
Other tables are linked to the Request table through a request id.
There is a TwitterTweet table and a FacebookPost table.
So a single request can have 50 TwitterTweets and/or 20 FacebookPosts or any amount of Tweets/Posts
We can add them together for a total count of 70.
I'm trying to create a query that could tell me what is the request with the highest total count.
I know this is wrong:
(I attempted to just order them by the counts within the TwitterTweet, but it would not let me do an OUTER JOIN which I thought
would bring back the Count.count column. It forced me to do a Left Join for it to compile. My Logic was to do a join so
that the results were calculated for each row by the requestid)
SELECT r1.`id` AS requestid, r1 . *
FROM `Request` AS r1
LEFT JOIN
(SELECT COUNT( * ) AS count, rid
FROM
((SELECT `TwitterTweet`.`id` AS `smid` , `TwitterTweet`.`requestid` AS rid
FROM `TwitterTweet`
WHERE `TwitterTweet`.`requestid` = requestid
AND `TwitterTweet`.`active` =1) AS talias
)) AS Count ON ( Count.rid = requestid )
ORDER BY Count.count
*When I tried to add in the Facebook side it would not compile any more
(The concept is that the results are added from TwitterTweet with the results from FacebookPost
that are attached to the specific requestid which would give us a count. The entire result
set should be ordered by that count)
SELECT r1.`id` AS requestid, r1 . *
FROM `Request` AS r1
LEFT JOIN
(SELECT COUNT( * ) AS count, rid
FROM
((SELECT `TwitterTweet`.`id` AS `smid` , `TwitterTweet`.`requestid` AS rid
FROM `TwitterTweet`
WHERE `TwitterTweet`.`requestid` = requestid
AND `TwitterTweet`.`active` =1 ) AS talias
UNION All
(SELECT `FacebookPost`.`id` AS `smid`, `FacebookPost`.`requestid` AS rid
FROM `FacebookPost`
WHERE `FacebookPost`.`requestid` = requestid
AND `FacebookPost`.`active` = 1) as falias
)) AS Count ON ( Count.rid = requestid )
ORDER BY Count.count
I updated the Query with an attempt to add an alias:
SELECT rid, SUM(count) total_count
FROM
(
(SELECT COUNT(*) AS count, r.rid
FROM request r
JOIN TwitterTweet tt
ON r.id = tt.requestid
WHERE tt.active = 1
GROUP BY r.rid) AS twitter
UNION ALL
(SELECT COUNT(*) AS count, r.rid
FROM request r
JOIN FacebookPost fp
ON r.id = fp.requestid
WHERE fp.active = 1
GROUP BY r.rid ) AS fbook
)
GROUP BY rid
ORDER BY SUM(count) DESC
I made another adjustment to give the middle subquery an alias, but now I only get one row returned with a zero in the rid column and 5686 in the total_count column...the 5686 might be all of the results.
SELECT counts.rid, SUM(count) total_count
FROM
(
SELECT COUNT(*) AS count, r.requestid AS rid
FROM request r
JOIN TwitterTweet tt
ON r.id = tt.requestid
WHERE tt.active = 1
GROUP BY r.requestid
UNION ALL
SELECT COUNT(*) AS count, r.requestid AS rid
FROM request r
JOIN FacebookPost fp
ON r.id = fp.requestid
WHERE fp.active = 1
GROUP BY r.requestid
) AS counts
GROUP BY counts.rid
ORDER BY SUM(count) DESC
Got it!!!
Thanks for your help guys, I had to remove those joins on the request:
SELECT counts.rid, SUM(count) total_count
FROM
(
SELECT COUNT(*) AS count, tt.requestid AS rid
FROM TwitterTweet tt
WHERE tt.active = 1
GROUP BY tt.requestid
UNION ALL
SELECT COUNT(*) AS count, fp.requestid AS rid
FROM FacebookPost fp
WHERE fp.active = 1
GROUP BY fp.requestid
) AS counts
GROUP BY counts.rid
ORDER BY SUM(count) DESC
SELECT id, SUM(count) total_count
FROM
(
SELECT COUNT(*) AS count, r.id
FROM request r
JOIN TwitterTweet tt
ON r.id = tt.requestid
WHERE tt.active = 1
GROUP BY r.id
UNION ALL
SELECT COUNT(*) AS count, r.id
FROM request r
JOIN FacebookPost fp
ON r.id = fp.requestid
WHERE fp.active = 1
GROUP BY r.id
) sub
GROUP BY id
ORDER BY SUM(count) DESC
;

GROUP_CONCAT multiple values from table

I just added a table which holds a url and description for each item in place. The below query works ok ... but it's only returning the url and I need the desc also. I m not sure how to make this work.
$query_str = "SELECT a.userid, a.cat, a.id, a.name, a.image,
a.desc, a.country, b.user_id, c.username,
c.fbook, d.cat_id,
(
SELECT GROUP_CONCAT(url)
FROM one_add o
WHERE a.id=o.one_id
) AS url,
(
SELECT COUNT(id)
FROM one_msg m
WHERE m.guest_id = ? AND
m.one_id=a.id
) AS count
FROM place a
LEFT OUTER JOIN wait b
ON a.id=b.post_id AND
b.user_id= ?
JOIN users c
ON a.userid=c.id
LEFT JOIN (
SELECT userid, user_id,
GROUP_CONCAT( cat_id ) AS cat_id
FROM user_cat
WHERE userid='$user_id'
GROUP BY user_id
) AS d ON d.userid='$user_id' AND
d.user_id=a.userid
WHERE a.cat != ? ORDER BY a.date desc";
This is what I want to accomplish: desc
You can achibe this by using CONCAT inside GROUP_CONCAT function as:
(SELECT GROUP_CONCAT(CONCAT('',desc,''))
FROM one_add o
WHERE a.id=o.one_id) AS url
full query:
(SELECT COUNT(id) FROM one_msg m WHERE m.guest_id = ? AND m.one_id=a.id ) AS count
FROM place a
LEFT OUTER JOIN wait b ON a.id=b.post_id AND b.user_id= ?
JOIN users c ON a.userid=c.id
LEFT JOIN ( SELECT userid, user_id, GROUP_CONCAT( cat_id ) AS cat_id FROM user_cat WHERE userid='$user_id' GROUP BY user_id ) AS d ON d.userid='$user_id' AND d.user_id=a.userid
WHERE a.cat != ? ORDER BY a.date desc";