I am trying to make a MySQLi query in PHP to a database that I have full of NHL Players and their projected stats/positions.
This is my query string - my goal is for it to return the top 10 projected goal scorers:
$goalSQL = 'SELECT * FROM players ORDER BY G LIMIT 10';
In my table, G is the column which holds the projected goal count for every player. I also have a column called "Position" which holds the position for every player (G, LW, RW, C, D).
However, I get back an object containing 10 goalies. I am guessing that the SQL is somehow taking my ORDER BY G to mean order by Position:G, but in reality I have no clue what is going wrong.
Any ideas?
Thanks!
If I had to guess, goalies have the lowest projected goal count. Try using desc:
SELECT p.*
FROM players p
ORDER BY p.G DESC
LIMIT 10;
Related
Maybe a stupid question, but I can't find anything on it. I know you can do counts and some basic math with queries.
Is there a way to make the database count and return results with the highest or lowest number of occurrences?
Lets say you had all the pages of a library in a database and you wanted to know the top 5 characters used or maybe the least used.
I guess the easiest example would be the lottery. Lets say you had a table of past lottery results. Lets say you wanted to return a list of the top 10 most drawn numbers. Lets say the numbers can range from 1 to 100.
It wouldn't be very efficient to run the following query 100 different times and then run some php to sort the data.
SELECT COUNT(*) FROM mytable WHERE ball=1
Surely there must be a way to return a count of the most duplicated data.
Perhaps I am over thinking this. Anyway, thanks for any help in the matter.
That's called grouping, the group by clause will let you do that, make sure you don't just pull out the count but also the thing you're counting, in this case ball.
Get the lowest number occurrences:
SELECT ball, COUNT(*) FROM mytable GROUP BY ball ORDER BY ball ASC limit 1;
Get the highest number occurrences:
SELECT ball, COUNT(*) FROM mytable GROUP BY ball ORDER BY ball DESC limit 1;
If you want them all in one result you can use a union/union all:
(SELECT ball, COUNT(*) FROM mytable GROUP BY ball ORDER BY ball ASC limit 1)
UNION ALL
(SELECT ball, COUNT(*) FROM mytable GROUP BY ball ORDER BY ball DESC limit 1);
you can simply use
SELECT column, COUNT(*)
FROM mytable
GROUP BY column_name
this will count all of the existing entries for the specific column_name
you should use column before COUNT(*) so you know what has that many values.
i hope this helps!
I have stumbled upon a problem that I can't get my head around.
I have the following topic related tables:
dive(ID,Type,Diver_id,Difficulty,Contest_id)
results(ID,Points,Judge_Id,Dive_id)
divers(ID,Name,Country)
My SELECT statement is meant to list the diver.Name, diver.Country and "total points"
The total points is supposed to be (total += ((dive_total -min -max)*difficulty))
Let's say a diver did 3 dives. Every dive has been rated by ~4 judges and every dive has it's own difficulty. The lowest/highest score per dive is supposed to be removed. Then added together, multiplied with the difficulty and then added to the persons total points.
I have got a list that shows diver.Name, diver.Country and Total.
But the total is only the actual total without the subtraction and multiplication.
Query:
SELECT
divers.Name,
divers.Country,
SUM(results.Points) AS Total
FROM results
INNER JOIN dive
ON results.Dive_id = dive.ID
INNER JOIN divers
ON dive.Diver_id = divers.ID
WHERE dive.Contest_id = '1'
GROUP BY divers.Name
ORDER BY Total DESC
Don't mind the contest_id. It's always '1'.
Please ask for more information if needed. Maybe the question is very silly. I am not a advanced "database guy". Sorry for bad English in advance.
(It is later printed in php/html. Maybe a language combination between mysql and php is a better way to move forward?)
I think what you want is this
SELECT
divers.Name,
divers.Country,
((SUM(results.Points) - MAX(results.Points) - MIN(results.Points)) * dive.Difficulty) AS Total
FROM results
INNER JOIN dive
ON results.Dive_id = dive.ID
INNER JOIN divers
ON dive.Diver_id = divers.ID
WHERE dive.Contest_id = '1'
GROUP BY divers.Name
ORDER BY Total DESC
Otherwise I would just change the SELECT to include:
MIN(results.Points) as maxPoints,
MAX(results.Points) as minPoints,
SUM(results.Points) as totalPoints
and then do the math side of it using PHP
Thank you ode2k! Very helpful. The end result with your code + some GROUP BY
SELECT
divers.Name,
divers.Country,
SUM(results.Points * dive.Difficulty) - MAX(results.Points * dive.Difficulty) - MIN(results.Points * dive.Difficulty) AS Total
FROM results
INNER JOIN dive
ON results.Dive_id = dive.ID
INNER JOIN divers
ON dive.Diver_id = divers.ID
WHERE dive.Contest_id = '1'
GROUP BY divers.Name,
dive.ID,
dive.Difficulty,
results.Dive_id
ORDER BY Total DESC
And then I added the the scores together in PHP to get every name just once.
I'm currently looking in MySQL to order results by price, and then output a random one with the highest price. (several will have the same price)
I've had a look at other stackoverflow questions and found people with answers saying that if two results are the same you cannot guarantee which one will be outputted however that sounds like a bit of a glitch/hack, is there anyway to order a table by the highest results and then chose a random one of those results?
$qry="SELECT * FROM campaignInformation ORDER BY campaignInformation.bidPerCustomer DESC LIMIT 1";
two of my "bidPerCustomers" are 0.25 and I would like to to chose a random one of these every time, however not choose one with a bet of 0.11 for example
Thanks in advance guys!
I'm asumming that I will have to make a query and then choose a random one from the results however it would be nice if I could do it in the query to begin with.
If you just want to select any from those with max value, then you can build it up cleanly:
SELECT * FROM campaignInformation C WHERE C.bidPerCustomer = (
SELECT MAX(D.bidPerCustomer) FROM campaignInformation D
)
That'll net you all rows that have max value. You can then select one from that table, LIMIT 1, order by RAND()
SELECT * FROM (
SELECT * FROM campaignInformation C WHERE C.bidPerCustomer = (
SELECT MAX(D.bidPerCustomer) FROM campaignInformation D
)
) AS X
ORDER BY RAND()
LIMIT 1
Every derived table needs an alias, hence the 'AS X'
Make sure you have an index on your bidPerCustomer column, or havoc ensues.
I've got following tables in my MySQL database:
USERS
iduser nick password
ARTICLES
idarticles iduser text
How can I get by one SQL query the list of e.g. 10 top publishers of articles ordering by the count of added articles? Is there any way to do that? I'm using PHP to ask database.
Yes, this should be quite easy via JOIN and COUNT(). Something like the following
SELECT `users`.`iduser`, COUNT(`articles`.`idarticles`) AS `total_articles`
FROM `users`
INNER JOIN `articles` ON `users`.`iduser` = `articles`.`iduser`
GROUP BY `users`.`iduser`
ORDER BY `total_articles` DESC
LIMIT 10
A little explaining:
COUNT() will get you what it says - a count of all relevant entries in articles
INNER JOIN will pair all entries that belong together (defined via ON)
GROUP BY tells SQL that you are interested in various results, each differing by iduser (without this, you'd get all articles counted in the first returned row)
ORDER BY .. DESC is important to get the result in a descending order (so most published first)
LIMIT 10 does exactly that
My search query runs like:
select * from posts p where p.post like '%test%' ORDER BY p.upvotes DESC,
p.unix_timestamp DESC LIMIT 20
If there are more than 20 results for the searched keyword, i find out the minimum timestamp value, store it in a hidden element and run another query to Load More results like:
select * from posts p where p.post like '%test%' and p.unix_timestamp < 1360662045
ORDER BY p.upvotes DESC, p.unix_timestamp DESC LIMIT 20
Whats really happening is that my first query is ignoring (Obviously, my mistake) posts which haven't had any votes(meaning 0 votes) because of my ORDER BY p.upvotes DESC and as a result of this, i noticed that it fetched the first post in the table in the first 20 results, so the minimum timestamp becomes first post's timestamp. Now after this, if i try to fetch the next 20 results which is less than the minimum timestamp, it doesn't give anything.
Right now, i am simply using the upvotes ordering to fetch top records. Should i be using some algorithm like Bayesian Average or some other algorithm?
Please advise how i can improve the queries if i had to stay with current system of ordering or is there any viable and more efficient method i should be using?
P.S. If possible, please refer some resources about the Bayesian Average(it seems to be most used) or some other alternative?
Storing the timestamp when you first do a search and then using that for the next query you could use something like this:-
$sql = "SELECT *
FROM posts p
LEFT OUTER JOIN (SELECT post_id, COUNT(*) FROM post_ratings WHERE timestamp_rated <= $SomeTimeStoredBetweenPages GROUP BY post_id) pr ON p.id = pr.post_id
WHERE p.post like '%test%'
ORDER BY pr.post_ratings DESC, p.unix_timestamp
DESC LIMIT ".(($PageNo - 1) * 20)." 20";
This is very much an example as I have no real idea of you table structures. Also not sure if you just have a row for each up vote, or whether there are down votes to take account of as well.