Ok so I don't think the question is as simple as the title suggests but here goes ...
I have this query:
SELECT age.*, job.id FROM age, job WHERE ((age.aid = job.id) AND (age.aid='$id'))
this basically joins the two tables age and job and gets matching rows
but now I need to find the most common age stored in row guess under the table age
DB layout
Table: age
rows: aid - guess
Table: job
Rows: id
From what I have found searching I need to use count()
eg:
SELECT guess, COUNT(guess) AS countguess FROM age GROUP BY guess ORDER BY countguess DESC LIMIT 1
but how can I merge the 2 queries together?
You could do something like this
SELECT age.aid, job.id, age.guess, COUNT(age.guess) AS countguess
FROM age, job
WHERE ((age.aid = job.id) AND (age.aid='$id'))
GROUP BY guess
ORDER BY countguess DESC
When you say merge, i think you mean joining them. You can join when there is a relationship between the 2 tables.
You can use UNION ALL to accomplish this
SELECT aid, id, guess, SUM(countguess ) AS countguess
FROM
(
SELECT age.aid, job.id, guess, 0 AS countguess
FROM age
INNER JOIN job
ON age.aid = job.id AND
age.aid='$id'
UNION ALL
SELECT age.aid, 0 AS job.id, guess, COUNT(guess) AS countguess
FROM age
GROUP BY guess
ORDER BY countguess DESC
LIMIT 1
) a
GROUP BY aid
*Note: UNION ALL requires same number of columns in both queries
SELECT age.*, job.id FROM age, job,
(SELECT AVG(guess) AS countguess FROM age GROUP BY guess ORDER BY countguess DESC LIMIT 1) AS countguess
FROM job AS j
INNER JOIN age AS a
ON j.id = a.aid
WHERE a.aid = '{$id}'
I'm not sure if this is what you want? Maybe
SELECT age.*, job.id FROM age, job,
(SELECT AVG(guess) AS countguess FROM age WHERE guess = a.guess GROUP BY '1') AS countguess
FROM job AS j
INNER JOIN age AS a
ON j.id = a.aid
WHERE a.aid = '{$id}'
Related
What I want to do with SQL is find repeating values in a column until there's an other value sorted by date.
This is my table. I use "CURRENT_TIMESTAMP" for the date column.
Name |date
-------------------
Bart |12-12-2014
Bart |23-12-2014
Joost |24-12-2014
Bart |25-12-2014
Bart |26-12-2014
Bart |27-12-2014
So in this example I want the number "3" returned and the last known value of name, so in this case "Bart".
I hope I made myself clear, sorry for the unclear title!
Hmmm . . . Here is one method where the logic is placed in the where clause:
select count(*), max(lastname.name)
from tablename t cross join
(select t2.name from tablename t2 order by date desc limit 1) as lastname
where t.name = lastname.name and
t.date > (select max(t2.date) from tablename t2 where t2.name <> lastname.name);
You can use the following query:
SELECT Name, COUNT(*) AS cnt
FROM (
SELECT Name, [date],
ROW_NUMBER() OVER (ORDER BY [date]) -
ROW_NUMBER() OVER (PARTITION BY Name ORDER BY [date]) AS grp
FROM mytable ) AS t
GROUP BY Name, grp
ORDER BY COUNT(*) DESC
This query tries to identify islands of records, i.e. consecutive rows having the same Name: grp calculated field does exactly this.
If you want the Name having the largest number of consecutive records, just use TOP 1 in the above query.
Demo here
Suppose I have a table named studens.
I want to count how many students who received duplicated scores at least 2 times.
Please help me, thanks.
The result that I expect is: Jonh have 100 score 2 times, James have 80 scores 2 times, Julia has 50 scores 2 times. So the amount of students who receive duplicated score at least 2 times is 3 (Jonh, Jam, and Julia).
select count(*) from
(
select name
from your_table
group by name, score
having count(*) > 1
) x
Based on the edit, your query would be:
select distinct name
from students
group by name, score
having count(*) > 1;
You could see the scores and counts by doing:
select name, score, count(*)
from students
group by name, score
having count(*) > 1;
By the way, the first query is one of the very, very few times where select distinct is appropriate with a group by. I think the second query provides more information, though.
Assuming a student has only one score per subject (that is, name, subject is unique):
SELECT COUNT(DISTINCT t1.name)
FROM scores t1
INNER JOIN scores t2
ON t1.name = t2.name
AND t1.subject <> t2.subject
AND t1.score = t2.score
SQLFiddle
I have a query that gets me a users rank in a table of scores.
SELECT
*
FROM
(SELECT
*, #rank:=#rank + 1 rank
FROM
(SELECT
user_id, SUM(round_total) TotalPoints
FROM
sx14sp_mem_picks
GROUP BY user_id) s, (SELECT #rank:=0) init
ORDER BY TotalPoints DESC) r
WHERE
user_id = 22234
There is a problem with ties. I have a table field "pick_date" that i would like to use to break ties with. The user who made his picks first beats the tie.
Any ideas?
If sx14sp_mem_picks.pickdate is the field to break ties then in the order by sx14sp_mem_picks subquery, add
min( pickdate) asc
This will put the earliest pickdate first - you have to use MIN() bc you need to use an aggregate function given the use of "group by".
You need to order by the pick date in addition to the total points. However, you are talking about multiple rows per user. So, let's take the last pick date:
SELECT *
FROM (SELECT *, (#rank:=#rank + 1) as rank
FROM (SELECT user_id, SUM(round_total) as TotalPoints, max(pick_date) as max_pick_date
FROM sx14sp_mem_picks
GROUP BY user_id
) s CROSS JOIN
(SELECT #rank := 0) init
ORDER BY TotalPoints DESC, max_pick_date asc
) r
WHERE user_id = 22234;
Issue
I have one table (posts) with articles and article meta.
Another table (post_reviews) contains user-submitted ratings (a value out of 5) for each article, referencing posts by the id of the post in question.
I am trying to find the top three posts, by review, of the last 3 days. Therefore I need to:
find all the posts in that time period (3 days)
find the average rating for each post
sort them by average rating (desc)
Code
For the first part, I can successfully use the query:
SELECT * FROM `posts` WHERE `hub_id`=:hub_id AND `date`>=:start_date AND `date`<=:end_date)
To find each individual post's average rating, I use this query:
SELECT SUM(`review`) AS `total` FROM `post_reviews` WHERE `id`=:id
then get the number of rows from this to work out the average:
SELECT * FROM `post_reviews` WHERE `post_id`=:id
How can I combine these three, or process this data so I can order the posts in a time period by the average rating?
ANSWER
The end result looks like this:
SELECT `posts`.`id`, avg(`post_reviews`.`review`) as `average`
FROM `posts`
JOIN `post_reviews` ON (`posts`.`id`=`post_reviews`.`post_id`)
WHERE `hub_id`=:hub_id
AND `posts`.`date`>=:start_date
AND `posts`.`date`<=:end_date
GROUP BY `post_id`
ORDER BY avg(`review`) desc
Not sure what your hub_id represents, but I assume it's necessary; also assume the key field in Posts is posts.post_id and not posts.id:
SELECT `p`.`id`, avg(`pr`.`review`) AS `average`
FROM `posts` AS `p`
JOIN `post_reviews` AS `pr` ON (`p`.`id`=`pr`.`post_id`)
WHERE `hub_id` =:hub_id
AND `p`.`date` BETWEEN CURRENT_DATE-3 AND CURRENT_DATE
GROUP BY `p`.`id`
ORDER BY avg(`review`) DESC;
See Example: sqlfiddle
Not sure about the syntax for MySQL, but the would need a join and a group by.
Something like....
SELECT post_id. avg(review)
FROM Posts P Inner Join Post_reviews PR on (p.post_id = pr.Post_id)
WHERE `hub_id`=:hub_id AND `date`>=:start_date AND `date`<=:end_date)
Group by Post_id
order by 2 desc
Here is a query that works with sqlfiddle to prove it.
SELECT
p.hub_id
,p.post_id
,p.article
,p.articleMeta
,p.date
,IFNULL(AVG(r.ratings), 0) averageRating
FROM posts p
LEFT JOIN post_reviews r ON
r.post_id = p.post_id
WHERE
hub_id = 1
AND date >= CURDATE() - 3
AND date <= CURDATE()
GROUP BY
p.hub_id
,p.post_id
,p.article
,p.articleMeta
,p.date
ORDER BY
p.date DESC
,averageRating DESC
http://sqlfiddle.com/#!2/39315/1
I have a 1 table database that has a list of advertisements.
I am trying to grab the LATEST advertisement for EACH resort.
I know it should probably be a table database, but how would I go about doing so.
Assuming the Id column is unique:
SELECT T3.*
FROM yourtable AS T3
JOIN
(
SELECT T2.resort, T2.date_added, MAX(T2.id) AS id
FROM yourtable AS T2
JOIN
(
SELECT resort, MAX(date_added) AS date_added
FROM yourtable
GROUP BY resort
) AS T1
ON T1.resort = T2.resort AND T1.date_added = T2.date_added
GROUP BY T2.resort, T2.date_added
) AS T4
ON T4.id = T3.id
select t.*
from YourTable t
join
(select resort, max(dateAdded) dateAdded
from YourTable
group by resort) m on t.dateAdded = m.dateAdded and t.resort = m.resort
order by t.resort
First group the rows by resort to find the max of dateAdded, then query (join) the rows that have the same dateAdded with the max.
One problem is, if the same resort b is added in the same time, twice or more, it will take only the first row. But I think is slightly possible.
Have a look at this article for selecting the "maximum" (say, most recent date) item from a group of items.
Use GROUP BY function
SELECT MAX(dateAdded), resort, linkToUrl FROM `your_table` GROUP BY resort
I think this should do it:
SELECT * FROM advertisements GROUP BY resort ORDER BY dateAdded DESC