Count Most donator SQL - mysql

I wanted to know how would i count most donated number for a person and how to make list from most donator to the lowest.
Database looks like this :
- Donated Amount - Payer Email
- 10 123456#hotmail.com
- 5 125643#hotmail.com
- 5 123456o#gmail.com
- 20 6653211#live.de
- 5 1256431#live.de
- 10 6558714#gmail.com
Note : If anyone would guide me on how the table is made on stackoverflow, thank you.

The easiest is to group by the email, sum the amount to get a total, and order by descending total.
SELECT
`Payer Email`,
SUM(`Donated Amount`) AS DonatedAmount
-- , COUNT(*) AS TimesDonated
-- , MAX(`Donated Amount`) AS BiggestDonation
FROM YourDonationsTable
GROUP BY `Payer Email`
ORDER BY DonatedAmount DESC
And if you want only the top 3 of those, add a LIMIT 3 at the end of the SQL.

Related

Count the number of registration by date

I am stuck with a select I have to do, I have a data base where a new claim file is registered in the table called “claims”, in this table every file is registered as follows :
Sorry, i have attached above a print screen with how the tables look, i don't know why are as bellow when i post it.
ClaimFileNumber || Vehicle number || ……. || OpeningDate
1 abc 20170302
2 bcd 20170302
3 efg 20170301
4 hij 20170301
I need a select which can help me to find out how many claim files are open on each day from when this year started until now, ordered by top 5 days for each month like for example, on the month of May we have: 20170506 - 300 claims, 20170511 – 295 claims, 20170509 – 200 claims etc.
Or it is ok a select which can give me the number of claims opened per day and order them desc.
The problem is that the date stored in table OpeningDate it is stored as numeric and not as date, this is the tricky part at least for me.
I cannot use a select like “select count (OpeningDate) from claim where openingdate = 20170302” for each day because there are more than 200 days from when the year have started.
Thank you in advance for your help.
This should do it:
SELECT OpeningDate, COUNT(OpeningDate)
FROM claim
WHERE LEFT(OpeningDate, 4) = '2017'
GROUP BY OpeningDate
ORDER BY OpeningDate ASC, COUNT(OpeningDate) DESC
You need group by:
select OpeningDate,count(1) from your_table group by OpeningDate
For top 5, you need order by and limit
select OpeningDate,count(1)
from your_table
group by OpeningDateorder
order by 2 desc
limit 5

Average value for top n records?

i have this SQL Schema: http://sqlfiddle.com/#!9/eb34d
In particular these are the relevant columns for this question:
ut_id,ob_punti
I need to get the average of the TOP n (where n is 4) values of "ob_punti" for each user (ut_id)
This query returns the AVG of all values of ob_punti grouped by ut_id:
SELECT ut_id, SUM(ob_punti), AVG(ob_punti) as coefficiente
FROM vw_obiettivi_2015
GROUP BY ut_id ORDER BY ob_punti DESC
But i can't figure out how to get the AVG for only the TOP 4 values.
Can you please help?
It will give SUM and AVG of top 4. You may replace 4 by n to get top n.
select ut_id,SUM(ob_punti), AVG(ob_punti) from (
select #rank:=if(#prev_cat=ut_id,#rank+1,1) as rank,ut_id,ob_punti,#prev_cat:=ut_id
from Table1,(select #rank:=0, #prev_cat:="")t
order by ut_id, ob_punti desc
) temp
where temp.rank<=4
group by ut_id;
This is not exactly related to the question asked, I am placing this because some one might get benefited.
I got the hackerearth problem to write mysql query to fetch top 10 records based on average of product quantity in stock available.
SELECT productName, avg(quantityInStock) from products
group by quantityInStock
order by quantityInStock desc
limit 10
Note: If someone can make better the above query, please welcome to modify.

SELECT the oldest of the most recent lines

I have a table storing the scores (with the date) of players they did at each game.
Example:
john 154 10/02/2014
mat 178 09/02/2014
eric 270 08/02/2014
mat 410 07/02/2014
john 155 06/02/2014
In this example I want "eric 270 08/02/2014" because thins is the oldest of the most recents.
Which request must I do to retrieve that ?
As I understand it, you request the oldest entry among the set containing the most recent one of each user.
In such a case, you can deal with your problem using a subquery given the last date for each user, then used in the main query to select and sort only the most recent entry of each user.
SELECT scores.*
FROM scores
INNER JOIN
(
SELECT max(date) last, name
FROM scores
GROUP BY name
) last_temp_table
ON scores.name = last_temp_table.name
AND scores.date = last_temp_table.last
ORDER BY scores.date ASC LIMIT 1;
More info in different SO threads such as MySQL order by before group by
The question as worded doesn't make much sense unless you define most recent.
If I assume that you have some criteria like: "Give the oldest event that happened within the last 3 days" then that is a simple matter of ordering and limiting across a date range.
select * from events where ts >= CURDATE() - 3
order by ts asc
limit 1

INSERT interpolated rows into existing table

I have a MySQL table similar to this simplified example:
orders table
--------------------------------
orderid stockid rem_qty reported
--------------------------------
1000000 100 500 00:01:00
1000000 100 200 01:10:00
1000000 100 200 03:20:00
1000000 100 100 04:30:00
1000000 100 50 11:30:00
:
1000010 100 100 00:01:00
1000010 100 100 01:10:00
1000010 100 20 03:20:00
:
1000020 200 1000 03:20:00
1000020 200 995 08:20:00
1000020 200 995 11:50:00
--------------------------------
The table comes from a 3rd party, weighs in at some 80-100M rows daily, and the format is fixed. It would be good, except it lacks rows showing when rem_qty reaches zero. The good news is, I can estimate them, at least a good upper/lower bound:
The 3rd party scans each distinct stockid at essentially random times throughout the day, and returns one row for each open orderid at that time. For example, stockid = 100 was scanned at (00:01, 01:10, 03:20, 04:30, 11:30). At each time, there will be a row for every current orderid with that stockid. Hence, one can see that orderid = 1000000 was still open at 11:30 (the last scan in our data), but sometime between 03:20 and 04:30, orderid = 1000010 sold out. (The times for stockid = 200 have no bearing on stockid = 100).
So, what I would like to do is INSERT the interpolated rows with rem_qty = 0 for each sold-out order. In this case, we can (only) say that orderid = 1000010 went to 0 at AVG('03:20:00','04:30:00'), so I would like to INSERT the following row:
orders table INSERT
--------------------------------
orderid stockid rem_qty reported
--------------------------------
1000010 100 0 03:55:00
--------------------------------
Trouble is, my SQL is rusty and I've not been able to figure out this complex query. Among other failed attempts, I've tried various JOINs, made a TEMPORARY TABLE stock_report(stockid,last_report), and I can do something like this:
SELECT orders.stockid,
orderid,
MAX(reported),
TIMEDIFF(last_report,MAX(reported)) as timediff
FROM orders
INNER JOIN stock_report
ON orders.stockid = stock_report.stockid
GROUP BY orderid
HAVING timediff > 0
ORDER BY orderid
This would show every sold-out order, along with the HH:MM:SS difference between the last time the orderid was reported, and the last time its stockid was reported. It's maybe a good start, but instead of last_report, I need to be able to calculate a next_report column (specific to this orderid, which would basically be:
SELECT MIN(reported) AS next_report
FROM orders
WHERE reported > #order_max_reported
ORDER BY reported
LIMIT 1
But that's just a vain attempt to illustrate part of what I'm after. Again, what I really need is a way to INSERT new rows into the orders() table at the AVG() time the order's rem_qty went to 0, as in the orders table INSERT example table, above. Or, maybe the 64,000 GFLOP question: would I be better off moving this logic to my main (application) language? I'm working with 100 million rows/day, so efficiency is a concern.
Apologies for the lengthy description. This really is the best I could do to edit for conciseness! Can anyone offer any helpful suggestions?
Possible to do. Have a sub query that gets the max reported time for each order id / stock id and join that against the orders table where the stock id is the same and the latest time is less that the order time. This gets you all the report times for that stock id that are greater than the latest time for that stock id and order id.
Use MIN to get the lowest reported time. Convert the 2 times to seconds, add them together and divide by 2, then convert back from seconds to a time.
Something like this:-
SELECT orderid, stockid, 0, SEC_TO_TIME((TIME_TO_SEC(next_poss_order_report) + TIME_TO_SEC(last_order_report)) / 2)
FROM
(
SELECT a.orderid, a.stockid, last_order_report, MIN(b.reported) next_poss_order_report
FROM
(
SELECT orderid, stockid, MAX(reported) last_order_report
FROM orders_table
GROUP BY orderid, stockid
) a
INNER JOIN orders_table b
ON a.stockid = b.stockid
AND a.last_order_report < b.reported
GROUP BY a.orderid, a.stockid, a.last_order_report
) sub0;
SQL fiddle here:-
http://www.sqlfiddle.com/#!2/cf129/17
Possible to simplify this a bit to:-
SELECT a.orderid, a.stockid, 0, SEC_TO_TIME((TIME_TO_SEC(MIN(b.reported)) + TIME_TO_SEC(last_order_report)) / 2)
FROM
(
SELECT orderid, stockid, MAX(reported) last_order_report
FROM orders_table
GROUP BY orderid, stockid
) a
INNER JOIN orders_table b
ON a.stockid = b.stockid
AND a.last_order_report < b.reported
GROUP BY a.orderid, a.stockid, a.last_order_report;
These queries might take a while, but are probably more efficient than running many queries from scripted code.

How would I do this in MySQL?

Lets say I have a database of widgets. I am showing a list of the top ten groupings of each widget, separated by category.
So lets say I want to show a list of all widgets in category A, but I want to sort them based on the total number of widgets in that category and only show the top 10 groupings.
So, my list might look something like this.
Top groupings in Category A
100 Widgets made by company 1 in 1990.
90 Widgets made by company 1 in 1993.
70 Widgets made by company 3 in 1993.
etc...(for 10 groupings)
This part is easy, but now lets say I want a certain grouping to ALWAYS show up in the listings even if it doesnt actually make the top ten.
Lets say I ALWAYS want to show the number of Widgets made by company 1 in 2009, but I want this grouping to be shown somewhere in my list randomly (not first or last)
So the end list should look something like
Top groupings in Category A
100 Widgets made by company 1 in 1990.
90 Widgets made by company 1 in 1993.
30 Widgets made by company 1 in 2009.
70 Widgets made by company 3 in 1993.
How would i accomplish this in MySQL?
thanks
Edit:
Currently, my query looks like this
SELECT
year,
manufacturer,
MAX(price) AS price,
image_url,
COUNT(id) AS total
FROM
widgets
WHERE
category_id = A
AND
year <> ''
AND
manufacturer <> ''
GROUP BY
category_id,
manufacturer,
year
ORDER BY
total DESC,
price ASC
LIMIT
10
);
Thats without the mandatory grouping in there.
The placement doesnt necessarily have to be random, just shouldnt be on any extreme end. And the list should be 10 groupings including the mandatory listing. So 9 + 1
I would use an UNION query: your current query union the query for 2009, then handle the sorting in the presentation layer.
You can write 2 separate query (one for all companies and another just for company 1) and then use UNION to join them together. Finally, add ORDER BY RAND().
It will look like
SELECT * FROM
(
SELECT company_id, company_name, year, count(*) as num_widgets
....
LIMIT 10
UNION DISTINCT
SELECT company_id, company_name, year, count(*) as num_widgets
...
WHERE company_id =1
...
LIMIT 10
)x
ORDER BY RAND();
You could add a field that you make true for company 1 in 2009 and include it in the where clause. Something like
select * from companies where group = 'some group' or included = true order by included, widgets_made limit 10
For the random part you would have that as subquery then include a column that has a random number from 1 to 10 if the field that you made is true, and rownum otherwise, then sort by that column