I have a businesses table. I want to get the owners name who has the most businesses. So far all I only know that I need to use GROUP BY and HAVING.
The problem is I only know the most basic queries...
Maybe something like this can help:
select owner, count(*) cntx
from businesses
group by owner
order by cntx desc
limit 1
Or executing the query without limit 1 clause, and then iterate the result till your needs are satisfied.
Use GROUP BY and order descending and then take the top one record which is the one that has most businesses:
select OwnerId, count(*) from businesses
group by OwnerId order by count(*) desc
limit 1
Related
I have a main table named tblorder.
It contains CUID(Customer ID), CuName(Customer Name) and OrDate(Order Date) that I care about.
It is currently ordered by date in ascending order(ex. 2001 before 2002).
Objective:
Trying to retrieve most recent 1 Million DISTINCT Customer's CUID and CuNameS, and Insert them Into a Tempdb(#Recent1M) for Later Joining Uses.
So I:
Would Need Order By desc to flip the date to retrieve most recent 1 Million Customers
Only want first 1 Million DISTINCT Customer Information(CUID, CuName)
I know following code is not correct, but it is the main idea. I just can't figure out the correct syntax. So far I have the While Loop with Select Into as the most plausible solution.
SQL Platform: SSMS
Declare #DC integer
Set #DC = Count(distinct(CUID)) from #Recent1M))
While (#DC <1000000)
Begin
Select CuID,CuName into #Recent1MCus from tblorder
End
Thank you very much, I appreciate any help!
TOP 1000000 is the way to go, but you're going to need an ORDER BY clause or you will get arbitrary results. In your case, you mentioned that you wanted the most recent ones, so:
ORDER BY OrderDate DESC
Also, you might consider using GROUP BY rather than DISTINCT. I think it looks cleaner and keeps the select list a select list so you have the option to include whatever else you might want (as I took the liberty of doing). Notice that, because of the grouping, the ORDER BY now uses MAX(ordate) since customers can presumably have multiple ordate's and we are interested in the most recent. So:
select top 1000000 cuid, cuname, sum(order_value) as ca_ching, count(distinct(order_id)) as order_count
into #Recent1MCus
from tblorder
group by cuid, cuname
order by max(ordate) desc
I hope this helps.
Wouldn't you just do this?
select distinct top 1000000 cuid, cuname
into #Recent1MCus
from tblorder;
If the names might not be distinct, you can do:
select top 1000000 cuid, cuname
into #Recent1MCus
from (select o.*, row_number() over (partition by cuid order by ordate desc) as seqnum
from tblorder o
) o
where seqnum = 1;
Use DISTINCT and ORDER BY <colname> DESC to get latest unique records.
Try this SQL query:
SELECT DISTINCT top 1000000
cuid,
cuname
INTO #Recent1MCus
FROM tblorder
ORDER BY OrDate DESC;
I want to ask you, if its correct if i use this ORDER BY in a SELECT COUNT(*)
Orginal: SELECT count(*) AS cnt FROM players WHERE totalpoints>?
Modified: SELECT count(*) AS cnt FROM players WHERE totalpoints>? ORDER BY timeontheserver DESC
In the Orginal query it outputs the players given "rank" in the database.
But i just noticed that some "players" are having the same amount of points and they get kinda reversed. So it should kinda give the player with an higher amount of "timeontheserver" the better "rank".
I hope you could understand this, thank you.
COUNT(*) will give you a number, you'll want to do a group by on the field you're ordering by to get what you want.
SELECT timeontheserver ,count(*) AS cnt FROM players
WHERE totalpoints>? GROUP BY timeontheserver ORDER BY timeontheserver DESC
I'm working on a project and I have a problem. I have a table namedfriendswith three columnid,from_emailandto_email(it's a social networking site and "from_email" is the person that follows the "to_email"). I want a query to return the top 5 friends I follow according to the number of their followers. I know that the query for top 5 is:
SELECT
to_mail,
COUNT(*) AS friendsnumber
FROM
friends
GROUP BY
to_email
ORDER BY
friendsnumber DESC
LIMIT 5
Any ideas?
I would also like to return friends with the same number of followers ordered by their name. Is it possible?
You should use COUNT(from_email) instead of COUNT(*); because you want to calculate the number of followers, which is represented by from_email.
Thus, your select clause would be something like:
SELECT to_email, COUNT(from_email) as magnitude
as for getting the most popular people that you follow, you could use IN clause:
WHERE to_email IN (SELECT to_email FROM friends WHERE from_email='MY_EMAIL');
and about name, you shall join this query with the other table which contains the name value.
Since you've got the essentials now, I hope you can try to compose the full query on your own =)
Join again to the table for the 2nd tier count:
SELECT f1.to_email
FROM friends f1
JOIN friends f2 on f2.to_mail = f1.to_email
WHERE f1.from_email = 'myemail'
GROUP BY 1
ORDER BY count(*) DESC
LIMIT 5
If an index is defined on to_email, this will perform very well.
First of all I'll just warn everyone that I'm something of a rookie with MySQL. Additionally I haven't tested the example queries below so they might not be perfect.
Anyway, I have a table of items, each one with a name, a category and a score. Every 12 hours the top item is taken, used and then removed.
So far I've simply been grabbing the top item with
SELECT * FROM items_table ORDER BY score DESC LIMIT 1
The only issue with this is that some categories are biased and have generally higher scores. I'd like to solve this by sorting by the score divided by the average score instead of simply sorting by the score. Something like
ORDER BY score/(GREATEST(5,averageScore))
I'm now trying to work out the best way to find averageScore. I have another table for categories so obviously I could add an averageScore column to that and run a cronjob to keep them updated and retrieve them with something like
SELECT * FROM items_table, categories_table WHERE items_table.category = categories_table.category ORDER BY items_table.score/(GREATEST(5,categories_table.averageScore)) DESC LIMIT 1
but this feels messy. I know I can find all the averages using something like
SELECT AVG(score) FROM items_table GROUP BY category
What I'm wondering is if there's some way to retrieve the averages right in the one query.
Thanks,
YM
You can join the query that calculates the averages:
SELECT i.*
FROM items_table i JOIN (
SELECT category, AVG(score) AS averageScore
FROM items_table
GROUP BY category
) t USING (category)
ORDER BY i.score/GREATEST(5, t.averageScore) DESC
LIMIT 1
Before I go on, I don't want to use ANY query which involves selecting all rows and counting the occurrences manually. I'm doing this in PHP by the way.
Basically, I have a bans table. Each new record/row is a new ban. The field titled user_name signifies which player was banned. Is there a way to count who has the most bans in this table? I really don't want to select every row and then count it out for each player. The table is pretty big, therefore making the mentioned solution impractical and inefficient.
This is done with COUNT() aggregates, grouping by user_name.
Get bans by user from most to least:
SELECT
user_name,
COUNT(*) as numbans
FROM bans
GROUP BY user_name
/* ordered by number of bans from greatest to least */
ORDER BY numbans DESC
Get only the most banned user:
SELECT
user_name,
COUNT(*) as numbans
FROM bans
GROUP BY user_name
ORDER BY numbans DESC
/* adjust LIMIT for how many records you want returned -- 1 gives only the first record */
LIMIT 1
In your question, you're very concerned about not wanting to count manually in PHP. Note that this is just about never necessary. RDBMS systems are designed explicitly for organizing and querying data, and are very good at doing tasks like this efficiently. Read up on GROUP BY clauses and aggregate functions in MySQL and master them. You generally shouldn't need to do it in code.
Bonus: Get all users banned 3 or more times
SELECT
user_name,
COUNT(*) as numbans
FROM bans
GROUP BY user_name
/* HAVING clause limits results of an aggregate like COUNT() (which you cannot do in the WHERE clause) */
HAVING numbans >= 3
gets the top 10 most banned (leave the limit line if you want to see all in order):
select user_name, count(user_name) as num_of_bans
from bans
group by user_name
order by num_of_bans desc
limit 10
SELECT user_name , COUNT( id )
FROM table_name
GROUP BY user_name