SQL query - how to display the most common value only - mysql

I have recently started to learn sql queries but i am having some issues.
I have these two tables here:
Birds
http://i.imgur.com/2m0VuoE.png
MembersLikesBirdEncounter (birdID is the foriegn key here referenced from above table Birds)
http://i.imgur.com/0cWlG94.png
i am trying to display the most common birdID value from the table MembersLikesBirdEncounter, which is 234. Below is the query i have come up with which doesn't seem to be working. What am i doing wrong?
SELECT m.birdID, COUNT(m.birdID)
FROM MembersLikesBirdEncounter m, Birds b
WHERE b.birdID = m.birdID
GROUP BY m.birdID
ORDER BY m.birdID DESC
LIMIT 1;
I want the output to be
birdID
------
234

Not so hard...
Instead:
GROUP BY Count(m.birdID) DESC

Never use commas in the FROM clause. Always use proper, explicit JOIN syntax. Then, the problem with your query is the ORDER BY column. You want to order by the count:
SELECT m.birdID, COUNT(m.birdID)
FROM MembersLikesBirdEncounter m JOIN
Birds b
ON b.birdID = m.birdID
GROUP BY m.birdID
ORDER BY COUNT(jm.birdID) DESC
LIMIT 1;
Then -- assuming that birdId refers always refers to valid birds -- the JOIN is not necessary. This should be sufficient:
SELECT m.birdID, COUNT(m.birdID)
FROM MembersLikesBirdEncounter m
GROUP BY m.birdID
ORDER BY COUNT(jm.birdID) DESC
LIMIT 1;

Related

Error while compiling statement: FAILED: SemanticException [Error 10002]

select d.order_type from migu_td_aaa_order_log_d d where exists(select 1
from migu_user r where r.user_id = '156210106' and r.user_num =
d.serv_number) and d.product_id in ('2028594290','2028596512','2028597138' )
order by d.opr_time desc limit 1
why the above sql failed ,indicates :
FAILED: SemanticException [Error 10002]: Line 4:11 Invalid column reference 'opr_time'
but the below one works :
select temp.order_type from (
select d.* from migu_td_aaa_order_log_d d where exists(select 1 from
migu_user r where r.user_id = '156210106' and r.user_num = d.serv_number)
and d.product_id in ('2028594290','2028596512','2028597138' ) order by
d.opr_time desc limit 1) temp;
this one works fine ,too ,and much more efficient than the second one:
select d.* from migu_td_aaa_order_log_d d where exists(select 1 from
migu_user r where r.user_id = '156210106' and r.user_num = d.serv_number)
and d.product_id in ('2028594290','2028596512','2028597138' )
order by d.opr_time desc limit 1
I only need to get order_type field,so even though the second one works,but it cost much more time.
Can anyone help me?
Thanks a lot!
Your first query does not work because, in the first select statement, you are just getting one column (d.order_type), but you are trying to order by another column (d.opr_time), which you have not included in your select statement
select d.order_type from ...
...
order by d.opr_time desc limit 1
Note that if you added the column d.opr_time to your first query, it would work:
select d.order_type, d.opr_time from ...
...
order by d.opr_time desc limit 1
Your second query works because, in the subquery, you have selected all the columns of d (d.*), so when you order by opr_time, that column is present. (Same for the third query).
select temp.order_type from (
select d.* ... order by d.opr_time ...
EDITED:
According to the Hive documentation:
When using group by clause, the select statement can only include
columns included in the group by clause. Of course, you can have as
many aggregation functions (e.g. count) in the select statement as
well.
So, this query:
select d.order_type, d.opr_time from ...
...
order by d.opr_time desc limit 1
Shouldn't work either, because the select clause has an additional column (d.order_type) that is not included in the group by clause.
I hope this helps.
P.S. This answer about SQL execution order might be useful.
1.
Hive currently have an order by limitation.
The current status of this issue is PATCH AVAILABLE.
see -
"Can't order by an unselected column"
https://issues.apache.org/jira/browse/HIVE-15160
2.
You might want to get familiar with LEFT SEMI JOIN which is a cleaner syntax for EXISTS
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Joins#LanguageManualJoins-JoinSyntax
3.
using min / max over a struct / named_struct can be used instead of order by ... asc / desc and limit 1
Here is an alternative solution:
select max(named_struct('opr_time',d.opr_time,'order_type',d.order_type)).order_type
from migu_td_aaa_order_log_d d
left semi join migu_user r
on r.user_num =
d.serv_number
and r.user_id = '156210106'
where d.product_id in ('2028594290','2028596512','2028597138')
;
P.s.
You seriously want to consider to treat IDs (user_id, product_id) as numeric and not as strings.

Multiple Order By in MySql Query

I am developing a voting system.
I am facing issue in ordering.
Basically i want to get top ranking and maximum nominee first. I used "totalUserVoted" and "totalRating" in Descending order on both condition but my query ordering "totalUserVoted".
I am expecting the result in this order.
Here is my sql query.
SELECT
(SELECT (((SUM(`design`)*4)+(SUM(`usability`)*3)+(SUM(`creativity`)*2)+(SUM(`content`))*1))/ count(`nominee_id`) / 10
FROM `sk_award_nominee_rating`
WHERE `sk_award_nominee_rating`.`nominee_id`=`sk_award_nominee`.`nominee_id`) AS totalRating,
(SELECT count(`nominee_id`)
FROM `sk_award_nominee_rating`
WHERE `sk_award_nominee_rating`.`nominee_id`=`sk_award_nominee`.`nominee_id`) AS totalUserVoted,
`sk_award_nominee`.*,
`sk_user`.`username`,
`sk_user`.`email`,
`sk_user_profile`.`f_name`,
`sk_user_profile`.`m_name`,
`sk_user_profile`.`l_name`,
`sk_user_profile`.`address`
FROM `sk_award_nominee`
LEFT JOIN `sk_user` ON `sk_user`.`user_id`=`sk_award_nominee`.`user_id`
LEFT JOIN `sk_user_profile` ON `sk_award_nominee`.`user_id`=`sk_user_profile`.`user_id`
WHERE `sk_award_nominee`.`status` = 1
AND DATE(approval_date) = '2016-02-22'
ORDER BY `totalUserVoted` DESC,
`totalRating` DESC
Something like this ?
ORDER BY totalUserVoted DESC, totalRating DESC
PHP MySQL Order by Two Columns

Order by COUNT(something) vs order by #column (sqlzoo example)

I was trying to solve problem 15 under http://sqlzoo.net/wiki/More_JOIN_operations
I don't understand why my query is wrong, even though my output is like it's supposed to be.
Here's my query:
SELECT movie.title, COUNT(actorid)
FROM movie JOIN casting on movie.id=movieid
WHERE yr='1978'
GROUP BY casting.movieid
ORDER BY COUNT(casting.actorid) DESC
And the official answer:
SELECT title, COUNT(actorid)
FROM casting,movie
WHERE yr=1978
AND movieid=movie.id
GROUP BY title
ORDER BY 2 DESC
If I just change the ORDER BY in my query from ORDER BY COUNT(casting.actorid) DESC to ORDER BY 2 DESC the answer is accepted (correct). Any reason for this?
All three of these should be accepted:
SELECT m.title, COUNT(c.actorid) as NumActors
FROM movie m JOIN
casting c
on m.id= c.movieid
WHERE yr = '1978'
GROUP BY c.movieid
ORDER BY COUNT(c.actorid) DESC
and:
ORDER BY 2 DESC
and:
ORDER BY NumActors DESC
Kudos for using proper explicit JOIN syntax. Simple rule: do not use commas in the FROM clause.
As a note: I think the use of 2 might be removed from some future version of the ANSI-compliant databases.
Yes - you can sort by the column ordinal. However you need to be aware that if the select list changes (if columns are added or removed, if the columns order is changed, etc..) you will see unexpected results if the order by clause is not modified to reflect the changes.
Some RDMBS's will allow you to give the column an alias and to use this in the order by clause. Not sure if MySql is one of those however.
SELECT movie.title, COUNT(actorid) NumMovies
FROM movie JOIN casting on movie.id=movieid
WHERE yr='1978'
GROUP BY casting.movieid
ORDER BY NumMovies DESC

I am trying this QUERY, and return this weird error,please help me

select tbl_c_food_veg.pk_veg_id,tbl_c_food_veg.var_desc,tbl_c_food_veg.var_title ,tbl_c_food_veg_img.var_img,( select tbl_c_food_non_veg.pk_non_veg_id,tbl_c_food_non_veg.var_desc,tbl_c_food_non_veg.var_title,tbl_c_food_non_veg_img.var_img from tbl_c_food_non_veg left join tbl_c_food_non_veg_img on tbl_c_food_non_veg.pk_non_veg_id=tbl_c_food_non_veg_img.fk_non_veg_id where
tbl_c_food_non_veg.fk_cat_id=8 and tbl_c_food_non_veg.pk_non_veg_id!=0 group by tbl_c_food_non_veg_img.fk_non_veg_id order by tbl_c_food_non_veg.pk_non_veg_id desc limit 2 ) as non_veg,( select tbl_c_food_drinks.pk_drinks_id, tbl_c_food_drinks.var_desc, tbl_c_food_drinks.var_title, tbl_c_food_drinks_img.var_img from tbl_c_food_drinks left join tbl_c_food_drinks_img on tbl_c_food_drinks.pk_drinks_id=tbl_c_food_drinks_img .fk_drinks_id where
tbl_c_food_drinks.fk_cat_id=8 and tbl_c_food_drinks.pk_drinks_id!=0 group by tbl_c_food_drinks_img.fk_drinks_id order by tbl_c_food_drinks.pk_drinks_id desc limit 2 ) as drinks from tbl_c_food_veg left join tbl_c_food_veg_img on tbl_c_food_veg.pk_veg_id=tbl_c_food_veg_img.fk_veg_id where
tbl_c_food_veg.fk_cat_id=8 and tbl_c_food_veg.pk_veg_id!=0 group by tbl_c_food_veg_img.fk_veg_id order by tbl_c_food_veg.pk_veg_id desc limit 2
In your nested sub queries for retrieving non_veg and drinks you use limit 2 so most likely the subquery will return 2 rows, but you can only use one row. Change the limit to limit 1
and try using aliases as Barranka says it wil be much easier to read your query

How to limiting subquery requests to one?

I was thinking a way to using one query with a subquery instead of using two seperate queries.
But turns out using a subquery is causing multiple requests for each row in result set. Is there a way to limit that count subquery result only one with in a combined query ?
SELECT `ad_general`.`id`,
( SELECT count(`ad_general`.`id`) AS count
FROM (`ad_general`)
WHERE `city` = 708 ) AS count,
FROM (`ad_general`)
WHERE `ad_general`.`city` = '708'
ORDER BY `ad_general`.`id` DESC
LIMIT 15
May be using a join can solve the problem but dunno how ?
SELECT ad_general.id, stats.cnt
FROM ad_general
JOIN (
SELECT count(*) as cnt
FROM ad_general
WHERE city = 708
) AS stats
WHERE ad_general.city = 708
ORDER BY ad_general.id DESC
LIMIT 15;
The explicit table names aren't required, but are used both for clarity and maintainability (the explicit table names will prevent any imbiguities should the schema for ad_general or the generated table ever change).
You can self-join (join the table to itself table) and apply aggregate function to the second.
SELECT `adgen`.`id`, COUNT(`adgen_count`.`id`) AS `count`
FROM `ad_general` AS `adgen`
JOIN `ad_general` AS `adgen_count` ON `adgen_count`.city = 708
WHERE `adgen`.`city` = 708
GROUP BY `adgen`.`id`
ORDER BY `adgen`.`id` DESC
LIMIT 15
However, it's impossible to say what the appropriate grouping is without knowing the structure of the table.