MySQL Select by Count + Sum of values - mysql

I have the following query (Wordpress DB).
This will return data for the comment that has the most combined "up" and "down" ratings:
$comment_query = $wpdb->get_results("
SELECT wp_comments.*, wp_comment_rating.*, (wp_comment_rating.ck_rating_up+wp_comment_rating.ck_rating_down) AS pop_comment
FROM wp_comments, wp_comment_rating
WHERE wp_comments.comment_post_ID = $post->ID
AND wp_comments.comment_ID = wp_comment_rating.ck_comment_id
AND wp_comments.comment_approved = 1
ORDER BY pop_comment
DESC
LIMIT 1");
However, I'd also like to factor in comments that have the most replies by counting the number of matched "comment_parent" per comment, then adding that total to the "pop_comment" value I'm ordering by.
Essentially, I want to get the data for a comment with the most combined replies and up/down ratings.
Hope that makes sense...

You could subquery to get the counts by comment_parent
$comment_query = $wpdb->get_results("
SELECT wp_comments.*, wp_comment_rating.*, (wp_comment_rating.ck_rating_up+wp_comment_rating.ck_rating_down + (
select count(*) from wp_comments c2 where c2.comment_parent=wp_comments.comment_ID
)) AS pop_comment
FROM wp_comments, wp_comment_rating
WHERE wp_comments.comment_post_ID = $post->ID
AND wp_comments.comment_ID = wp_comment_rating.ck_comment_id
AND wp_comments.comment_approved = 1
ORDER BY pop_comment
DESC
LIMIT 1");

This should work
Essentially its just a sub query to get the total comments for the comment_parent and then joins that as SubQ / SubCount to the field
comment_query = $wpdb->get_results("
SELECT wp_comments.*, wp_comment_rating.*, (SubCount + pop_comment) AS total_rank, (wp_comment_rating.ck_rating_up+wp_comment_rating.ck_rating_down) AS pop_comment
JOIN (SELECT COUNT(*) as SubCount, comment_parent as Sub_ID FROM wp_comments GROUP BY comment_parent) as SubQ
ON wp_comments.comment_ID = SubQ.Sub_ID
FROM wp_comments, wp_comment_rating
WHERE wp_comments.comment_post_ID = $post->ID
AND wp_comments.comment_ID = wp_comment_rating.ck_comment_id
AND wp_comments.comment_approved = 1 ORDER BY total_rank DESC LIMIT 1");

Related

Join between sub-queries in SQLAlchemy

In relation to the answer I accepted for this post, SQL Group By and Limit issue, I need to figure out how to create that query using SQLAlchemy. For reference, the query I need to run is:
SELECT t.id, t.creation_time, c.id, c.creation_time
FROM (SELECT id, creation_time
FROM thread
ORDER BY creation_time DESC
LIMIT 5
) t
LEFT OUTER JOIN comment c ON c.thread_id = t.id
WHERE 3 >= (SELECT COUNT(1)
FROM comment c2
WHERE c.thread_id = c2.thread_id
AND c.creation_time <= c2.creation_time
)
I have the first half of the query, but I am struggling with the syntax for the WHERE clause and how to combine it with the JOIN. Any one have any suggestions?
Thanks!
EDIT: First attempt seems to mess up around the .filter() call:
c = aliased(Comment)
c2 = aliased(Comment)
subq = db.session.query(Thread.id).filter_by(topic_id=122098).order_by(Thread.creation_time.desc()).limit(2).offset(2).subquery('t')
subq2 = db.session.query(func.count(1).label("count")).filter(c.id==c2.id).subquery('z')
q = db.session.query(subq.c.id, c.id).outerjoin(c, c.thread_id==subq.c.id).filter(3 >= subq2.c.count)
this generates the following SQL:
SELECT t.id AS t_id, comment_1.id AS comment_1_id
FROM (SELECT count(1) AS count
FROM comment AS comment_1, comment AS comment_2
WHERE comment_1.id = comment_2.id) AS z, (SELECT thread.id AS id
FROM thread
WHERE thread.topic_id = :topic_id ORDER BY thread.creation_time DESC
LIMIT 2 OFFSET 2) AS t LEFT OUTER JOIN comment AS comment_1 ON comment_1.thread_id = t.id
WHERE z.count <= 3
Notice the sub-query ordering is incorrect, and subq2 somehow is selecting from comment twice. Manually fixing that gives the right results, I am just unsure of how to get SQLAlchemy to get it right.
Try this:
c = db.aliased(Comment, name='c')
c2 = db.aliased(Comment, name='c2')
sq = (db.session
.query(Thread.id, Thread.creation_time)
.order_by(Thread.creation_time.desc())
.limit(5)
).subquery(name='t')
sq2 = (
db.session.query(db.func.count(1))
.select_from(c2)
.filter(c.thread_id == c2.thread_id)
.filter(c.creation_time <= c2.creation_time)
.correlate(c)
.as_scalar()
)
q = (db.session
.query(
sq.c.id, sq.c.creation_time,
c.id, c.creation_time,
)
.outerjoin(c, c.thread_id == sq.c.id)
.filter(3 >= sq2)
)

MySql sort by highest value with inner join and subquery

I have a query that has a sub query that returns a count of records from another table, I'm having trouble ordernar the largest number of this counter
SELECT respostas.id,
respostas.cmm,
respostas.topico,
respostas.usuario,
respostas.resposta,
perfis.nome,
perfis.sobrenome,
respostas.datahora,
(
SELECT count(id)
FROM likes
WHERE respostas.id = resposta
) AS total
FROM respostas
INNER JOIN perfis ON respostas.usuario = perfis.id
INNER JOIN likes ON respostas.topico = likes.topico
WHERE respostas.cmm = 28
AND respostas.topico = 38
ORDER BY respostas.id ASC, total ASC
LIMIT 0,20`enter code here`
I want to sort by the total column and can not.
Sorting by total does not work, only ordered by id
You can choose which column to order by numerically:
SELECT
(
SELECT count(id)
FROM likes
WHERE respostas.id = resposta
) AS total,
respostas.id,
respostas.cmm,
respostas.topico,
respostas.usuario,
respostas.resposta,
perfis.nome,
perfis.sobrenome,
respostas.datahora
FROM respostas
INNER JOIN perfis ON respostas.usuario = perfis.id
INNER JOIN likes ON respostas.topico = likes.topico
WHERE respostas.cmm = 28
AND respostas.topico = 38
ORDER BY 1, respostas.id
LIMIT 0,20
What is the purpose of Order By 1 in SQL select statement?

MySQL - combining multiple queries

I currently have the following queries (and some surrounding vB code). I was hoping I could slim this up into a single SELECT statement versus having to run 10 more on each page to get that names of individuals.
$results = $db->query_read_slave("
SELECT user.id AS steam, user.skills AS level
FROM wcsp.wcgousers AS user
WHERE race = '_wcs_'
ORDER BY ABS(user.skills) DESC LIMIT 10
");
$rank = 1;
while ($user = $db->fetch_array($results)) {
$result = $db->query_first("
SELECT old.name AS name
FROM wcsp.warn_oldnames AS old
WHERE id = '$user[steam]'
ORDER BY lasttime
DESC LIMIT 1
");
$listing[] = array("id" => $user['steam'], "level" => $user['level'], "name" => $result['name'], "rank" => $rank);
$rank += 1;
}
I have tried LEFT JOIN but the issue I run into is that I would need a subquery in the LEFT JOIN similar to:
SELECT user.id AS steam, user.skills AS level, names.name AS name
FROM wcsp.wcgousers AS users
LEFT JOIN
(
SELECT names.name
FROM wcsp.warn_oldnames AS names
WHERE id = wcsp.wcgousers.id
ORDER BY lasttime DESC LIMIT 1
) AS names
ON names.id = users.id
WHERE users.race = '_wcs_'
Which won't work due to the different database check inside the subquery.
If I understand you correctly, you want to get the latest Name for every users.
SELECT a.id AS steam,
a.skills AS level,
b.name
FROM wcgousers a
INNER JOIN warn_oldnames b
ON a.ID = b.ID
INNER JOIN
(
SELECT ID, MAX(lasttime) max_date
FROM warn_oldnames
GROUP BY ID
) c ON b.ID = c.ID AND
b.lastTime = c.max_date
WHERE a.race = '_wcs_'
-- ORDER BY ABS(a.skills) DESC
-- LIMIT 10

MySQL - "Most social User" with the most comments in multiple tables

I have 2 tables of concern - 'videoComments', 'storyComments'.
I need to find the 'posterID' that has the most entries in videoComments and storyComments. Here's the code I have so far, but it only calls videoComments:
$sql = "SELECT (SELECT posterID
FROM videoComments
GROUP BY posterID
ORDER BY COUNT(posterID) DESC LIMIT 1) ) AS mostSocialUser ";
How do I pull it and compare the COUNT of posterID from both tables?
Use:
SELECT x.posterid,
COUNT(y.posterid) + COUNT(z.posterid) AS numComments
FROM (SELECT vc.posterid
FROM VIDEOCOMMENTS vc
UNION
SELECT sc.posterid
FROM STORYCOMMENTS sc) x
LEFT JOIN VIDEOCOMMENTS y ON y.posterid = x.posterid
LEFT JOIN STORYCOMMENTS z ON z.posterid = x.posterid
GROUP BY x.posterid
ORDER BY numComments DESC
LIMIT 1
Try this:
SELECT (
SELECT posterID FROM (
SELECT posterID FROM videoComments
UNION
SELECT posterID FROM storyComments
) GROUP BY posterID
ORDER BY COUNT(posterID) DESC LIMIT 1
) AS mostSocialUser

SQL Join With Limit Range

I'm trying to add a limit range to my sql join statement so I can do pagination of my records, but when I enter in the limit range to my statement I'm getting nothing returned. With the limit range taken out it all works fine.
Here is what I have:
$sql= "SELECT R.id,companyName,membershipID,addressID,city,logo,descriptionShort FROM yt_Business_RegInfo R
INNER JOIN yt_Business_Seasons S
ON R.id = S.busID AND S.deleted = '0'
INNER JOIN yt_Business_Address A
ON R.addressID = A.id
INNER JOIN yt_Business_Membership M
ON R.membershipID = M.id AND M.approved = 1
WHERE R.deleted = '0'
ORDER BY R.companyName ASC LIMIT $start, $limit";
Any suggestions would be appreciated. Thanks.
That should be:
LIMIT $start, $howMany
If ($howMany <= 0) or ($start > number of rows returned without LIMIT) , then you get 0 results.
Echo the query:
echo $sql;
And check the values of $start and $limit that goes into it.