MySQL & PHP - Select 6 rows, each with a different 'WHERE' clause - php

I'm pretty good with MySQL, but this is something I have never done. What I want to do is make an SQL code to select 6 rows, each with their own WHERE clause.
What I am trying to do is get 6 rows, and each will be the most recent "video" that was posted. there are 6 categories, so that's why I have 6 rows. I want it to pull the most recent by it 'id' number.
I'd do it with 6 different SQL queries, but I assume that would be slower (unless this is the only way to do this?)
From that small snippet, I would like to end up with is this:
2 --> 21
6 --> 16
8 --> 14 (Picks 14 since it's largest.)
Final Working Code
$sql="SELECT video_category, MAX(video_id) AS video_id FROM videos GROUP BY video_category";
$result=mysql_query($sql);
while($rows=mysql_fetch_array($result)) {
echo $rows['video_category'] . " --> " . $rows['video_id'] . "<br>";
}

something like
select distinct category, video_id from table_name order by id DESC
If you have 6 categories in the db, you would get 6 rows, all having highest id in their category

Please share your table structure. Nevertheless, i think the following query should do the trick:
SELECT category_id, MAX(movie_id) most_recent_movie_for_category FROM movies GROUP BY category_id

Thanks for posting the table structure. This is just a simple GROUP BY with a MAX aggregate on video_id.
SELECT video_category, MAX(video_id) AS video_id FROM videos GROUP BY video_category;

You have two options:
Determine common WHERE clause that will result in what you need.
(probably preferred one) Make some query involving UNION (SELECT ... FROM ... WHERE ... UNION SELECT ... FROM ... WHERE ... etc.)
Let me know if you have any questions. I believe without your database structure it would be hard to help you more.

Related

Get previous 10 row from specific WHERE condition

Im currently working on a project that requires MySql database and im having a hard time constructing the query that i want get.
i want to get the previous 10 rows from the specific WHERE condition on my mysql query.
for example
My where is date='December';
i want the last 10 months to as a result.
Feb,march,april,may,june,july,aug,sept,oct,nov like that.
Another example is.
if i have a 17 strings stored in my database. and in my where clause i specify that WHERE strings='eyt' limit 3
Test
one
twi
thre
for
payb
six
seven
eyt
nayn
ten
eleven
twelve
tertin
fortin
fiftin
sixtin
the result must be
payb
six
seven
Thanks in advance for your suggestions or answers
If you are using PDO this is the right syntax:
$objStmt = $objDatabase->prepare('SELECT * FROM calendar ORDER BY id DESC LIMIT 10');
You can change ASC to DESC in order to get either the first or the last 10.
Here's a solution:
select t.*
from mytable t
inner join (select id from mytable where strings = 'eyt' order by id limit 1) x
on t.id < x.id
order by t.id desc
limit 3
Demo: http://sqlfiddle.com/#!9/7ffc4/2
It outputs the rows in descending order, but you can either live with that, or else put that query in a subquery and reverse the order.
Re your comment:
x in the above query is called a "correlation name" so we can refer to columns of the subquery as if they were columns of a table. It's required when you use a subquery as a table.
I chose the letter x arbitrarily. You can use anything you like as a correlation name, following the same rules you would use for any identifier.
You can also optionally define a correlation name for any simple table in the query (like mytable t above), so you can refer to columns of that table using a convenient abbreviated name. For example in t.id < x.id
Some people use the term "table alias" but the technical term is "correlation name".

Confusion with Avg() and Joining 2 tables

I've got myself into a bit of a tiss over averaging and joining tables.
Essentially I want to display the average heights of different plant species using Highcharts, pulling the data from a MySQL database. Unfortunately the height data and the species names were setup to be added in different tables.
I've got it working, however when I download the data and find the averages in Excel the figures are different to those being displayed - so I'm obviously not doing it right. I've double checked I'm doing it right in Excel so almost certain it's my MySQL query that's stuffing up.
There's loads of entries in the actual tables, so I've just put an example below.
The query I have at the moment is:
<?php
$result = mysql_query("
SELECT DISTINCT(plant_records.plant_id), ROUND(AVG(plant_records.height),2) as plant_average, plant_list.id, plant_list.plant_species
FROM plant_records
INNER JOIN plant_list
ON plant_records.plant_id=plant_list.id
GROUP BY plant_list.plant_species
") or die(mysql_error());
while ($row = mysql_fetch_array($result)) {
$xAxisValues[] = "'" . $row['plant_species'] . "'";
$AseriesValues[] = $row['plant_average'];
}
?>
Am I doing it right? I found some nice tutorials explaining joins, like this one, but I'm still confused. I'm wondering if I'm averaging before I've joined them, or something??
"plant_id" in the Records table corresponds with "id" in the List table
plant_records:
id plant_id date_recorded height
1 3 01/01/2013 0.2523123
2 1 02/01/2013 0.123
3 3 03/02/2013 0.446
4 3 04/03/2013 0.52
5 1 05/03/2013 0.3
6 2 06/03/2013 0.111
7 2 07/05/2013 0.30
8 4 08/05/2013 0.22564
9 1 09/05/2013 1.27
10 3 10/05/2013 1.8
plant_list:
id registration_date contact_name plant_species plant_parent
1 01/01/2013 Dave ilex_prinos London_Holly
2 02/01/2013 Bill acer_saccharum Brighton_Maple
3 01/01/2013 Bob ilex_prinos London_Holly
4 04/01/2013 Bruno junip_communis Park_Juniper
EDIT:
I've tried every possible way of finding the data using Excel (e.g. deliberately not filtering unique IDs, different average types, selecting multiple species, etc) to find the calculation my query is using, but I can't get the same results.
I notice two issues with your query at the moment.
Selecting plant_list.id while having a GROUP BY plant_list.plant_species will not yield anything of interest, due to the fact that MySQL will return an arbitrary id from any of the plants that match each species.
You state that you are only interested in the most recent recording, but nothing in your query reflects that fact.
Given that information, try this query:
SELECT ROUND(AVG(pr.height),2) as plant_average, plant_list.plant_species
FROM plant_records pr
INNER JOIN plant_list
ON pr.plant_id=plant_list.id
WHERE pr.date_recorded = (
SELECT MAX(pri.date_recorded) FROM plant_records pri
WHERE pri.plant_id = pr.plant_id
)
GROUP BY plant_list.plant_species
Alternately, if you want just the average heights for a specific date, simply pass that directly into the query, instead of using the subquery.
If we are assuming that plant_id is not the unique identifier - meaning that a single plant_id is only for one single plant of any given species and you want to know what the average height of a single species is you can do this:
SELECT PL.plant_species, ROUND(AVG(PR.height),2) as plant_average
FROM plant_records AS PR
JOIN plant_list AS PL
ON PR.plant_id=PL.id
GROUP BY PL.plant_species
This will return something like:
plant_species plant_average
acer_saccharum 0.2100000
ilex_prinos 0.6700000
junip_communis 0.2300000

show matching mysql table results only once?

hi I'm looking for a way to only show a matching set of mysql results only once. can anyone tell me how to do this?
here's an example of what i'm trying to achieve:
id | profile_id | viewed_profile_id | date_viewed
1 4 7 00:00:00
2 5 6 00:00:00
1 4 7 00:00:00
so if profile_id and viewed_profile_id match then to only show one result for those matching columns rather than twice or three times or however many times it appears in the database?
Use the DISTINCT keyword:
SELECT DISTINCT id, profile_id, viewed_profile_id, date_viewed
FROM myTable
This will show only one row for each unique combination of the columns selected.
Or, reading into your question a lot (since you only want to match profile_id and viewed_profile_id), if you want to show the latest date viewed for each viewer, you can use GROUP BY and select the MAX date viewed. I am also assuming there is data in date_viewed and it is sortable:
SELECT profile_id, viewed_profile_id, MAX(date_viewed)
FROM myTable
GROUP BY profile_id, viewed_profile_id
DISTINCT helps to eliminate duplicates. If a query returns a result that contains duplicate rows, you can remove duplicates to produce a result set in which every row is unique. To do this, include the keyword DISTINCT after SELECT and before the output column list
http://dev.mysql.com/doc/refman/5.0/en/distinct-optimization.html
SELECT DISTINCT(` profile_id`),`viewed_profile_id`,`id`,`date_viewed` FROM `tableName` GROUP BY `viewed_profile_id`
try this:
$query = "SELECT * FROM TABLENAME WHERE profile_id = '$PROFILEIDVALUE' AND viewed_profile_id = '$VIEWEDIDVALUE' LIMIT 0, 1"
Depending upon the ORDER you want use can use ORDER BY id DESC/ASC
I hope this would be useful

Apply a limit of 10 after taking distinct records in mysql

In a MySQL table, I would like to take 10 records with DISTINCT values.
I am using Zend Framework.
$select = $this->getAdapter()->select()
->from('table', 'column')->group('column')
->limit(10, 0);
This is the query generated by the above code.
SELECT table.column FROM
table GROUP BY column LIMIT 10
What happens here is that MySQL is taking 10 records first and then applying the group by. So finally, I am getting only 7 records.
How to apply DISTINCT first and then take 10 records from it?
Test that SQL against a table -- MySQL applies the limit last, so doesn't do what you're saying. eg test against
a0 a1
1 1
2 1
3 2
4 2
and do select A.a1 from A group by a1 limit 2. You should see 1, 2, not 1, 1.
[I wanted to say this as a 'comment' rather than an 'answer', but couldn't]
I'm not 100% sure what you are trying to do.
But if i am reading it correct you need 10 records with a certain criteria and then apply the group. not the other way around.
Can't you use WHERE in this case?
SELECT table.column FROM table WHERE "criteria" GROUP BY column LIMIT 10
Regards
Mike
This may help you (I didn't test it but so I'm not sure it's working)
SELECT DISTINCT column FROM table LIMIT 10
If it's not working, you may use a temporary table (like (SELECT column FROM table) TEMP), which will select the distinct elements, then a query which will select the first ten results into this table.
Hope this'll help :)
In ZF, You should use distinct() method into Your query chain :
$select = $this->getAdapter()->select()
->distinct()
->from('table', 'column')
->limit(10, 0);
SELECT DISTINCT column
FROM table
LIMIT 10
GROUP BY column
Not sure how to get it into classes though...

php / mysql - how to get rankings of users?

for example i have a table like this :
name rating
matei 124
andrei 20
serj 25
john 190
mike 96
andy 245
tom 73
i need to output something like this(order by rating):
john's position is 2; or, tom's position is 5; (i don't need to get all result , just one )
How can I achieve this?
Thanks in advance
Generally order of rows in a query result is not guaranteed by MySQL unless ordering is explicitly specified with ORDER BY clause. If you have some separate ordering column, you may use query like the following:
SELECT count(1) as position
FROM table
WHERE order_column <= {john's order_column value};
If you don't have ordering column, I'd recommend you to define first, what does "john's position" and "tom's position" mean.
UPDATE:
AFAIU, you want to get position in list sorted by rating (sorry, I initially did not get it). So, rating would be your order_column. In this case, you should decide, how do you calculate position, if two guys have equal rating (who's position is higher?).
So, the query may look in the following way:
SELECT count(1) as position
FROM table
WHERE
rating > (SELECT rating FROM table WHERE id={user's ID});
SELECT COUNT(*) + 1
FROM users
WHERE (rating, name) <
(
SELECT rating, name
FROM users
WHERE name = 'john'
)
Note that if you will have duplicates on both name and rating, this query will assign the same rating to both of them.
Tables are more formally known as relations in database literature - they are not guaranteed to be ordered (they are sets of "tuples"), so your question doesn't make sense. If you need to rely on an order/position, you need to define an additional column (like an auto-incrementing ID column) to capture and store that info.
Is this any help > http://craftycodeblog.com/2010/09/13/rownum-simulation-with-mysql/ ?
Would offset not work like so?
SELECT * FROM Table ORDER BY rating DESC LIMIT 1,6
This would return 1 row that has been off setted by 6 rows ? or am I mistaken, the syntax would be
SELECT * FROM Table ORDER BY rating DESC LIMIT 1 , {{POS}}

Categories