SQL PHP get full row with MAX i a single table - php

i have one table collecting scores and other informations like the date and the user id. I would like to get the MAX of the current month and the other fields of the row. I'm having a problem to get the other informations since with functions we cannot get other fields.
I think i should do an inner join but i don't how to make it.
Thank you.

Your question is rather vague. But if you want one row, then the idea for the solution is order by and fetch first row only.
In standard SQL, the query would look like:
select t.*
from t
where extract(year from datecol) = extract(year from current_date) and
extract(month from datecol) = extract(month from current_date)
order by t.score desc
fetch first 1 row only;
Databases often differ on database functions. For instance, many use year() and month() functions, rather than extract(). Similarly, many databases do not support fetch first 1 row only, using limit or select top instead.

Thank you, yes it does work doing this way but the idea was to use MAX (for learning purpose).

I have scores table, with the following fields: id, score, date, user_id
I would like, using MAX, to get the best and latest score of the current month along with the other fields (ie the id, date and user_id).

Related

Get first/last value from SQL selection using PHP

I have a SQL query in my php file (I use this file to calculate graphic timeblocks based on starting time and duration of an event; starttime and duration are my columns in SQL table).
How can I print/get last or first value from selection below using php? I mean first or last value from column 'starttime' to be precise.
$query1=mysqli_query($db,"select * from LISTS where category='planner'
order by date,timestart asc");
I googled since I am very much beginner but results did not make much sense because I don't have much skills yet. Therefore I am asking you.
Thanks in advance. Also can you please explain in very primitive way, some terms I might not understand at this point.
If you wan't both the first and last value in one MySql state you can use "Union". The UNION operator is used to combine the result-set of two or more SELECT statements.
To get either first or last value use "limit" and set this to 1, then order by asc or desc.
Example:
select * from LISTS where category='planner' order by date,timestart asc
limit 1) union (select * from LISTS where category='planner' order by
date, timestart desc limit 1
So I decided to find only first value based on my selection. I had to show it on the page, this is what worked for me.
$query3=mysqli_query($db,"select datetime from LISTS where
category='planner' order by date,timestart asc");
$SelectionArray=mysqli_fetch_array($query3);
$FIRSTdatetime=reset($SelectionArray);
echo $FIRSTdatetime;

Select from multiple tables using union all and single order by ,php

I ran into an error I cant seem to come out of.
am not too good with unions
I want to loop through 4 different tables(using union all) and manipulate their values to fit my needs.
I also need to use single 'ORDER by Date DESC' (Date are integer values) for the whole union all, so that I can arrange the output in a pattern,
when I add the 'order by date desc ' to it, code doesn't work . and when I remove it , the values of the second query are attached to the names of the first query, am sooo confused.
I tried "Select * from table_name where..... it idnt work in this case , that's why I had to bring out all table_names I need to the query,
Basically , I want to echo each value from the query uniquely when I need to,
any help is appreciated, thanks
<?php
$q114="(SELECT id AS id1,text_post AS text_post1,likes AS likes1
FROM timeline_posts WHERE email='$owner_email')
UNION ALL (SELECT pic_comment AS pic_comment2, comments AS comments2, date AS date2
FROM pictures WHERE email='$owner_email')
UNION ALL (SELECT image AS image3,likes AS likes3, comments AS comments3
FROM profile_pics WHERE email='$owner_email')
UNION ALL (SELECT likes AS likes4, comments AS comments4, date AS date4
FROM friends_timeline_post WHERE timeline_email='$owner_email')
ORDER BY 'date' DESC";
$pages_query=mysqli_query($connect,$q114);
while($fetch9=mysqli_fetch_assoc($pages_query))
{
print_r($fetch9['likes3'] );
//a lot of work to be done here
}
?>
For "unioning" the results of multiple selects and ordering those results by a column name across all the results of the multiple selects, column names must be the same in all selects.
You could add a column to all selects that would contain your "digit" in order to still be able to distinguish between let say "likes1" and "likes2" even if their column name is "likes" for all the selects that you "unioned".

How to order the ORDER BY using the IN() mysql? [duplicate]

I am wondering if there is away (possibly a better way) to order by the order of the values in an IN() clause.
The problem is that I have 2 queries, one that gets all of the IDs and the second that retrieves all the information. The first creates the order of the IDs which I want the second to order by. The IDs are put in an IN() clause in the correct order.
So it'd be something like (extremely simplified):
SELECT id FROM table1 WHERE ... ORDER BY display_order, name
SELECT name, description, ... WHERE id IN ([id's from first])
The issue is that the second query does not return the results in the same order that the IDs are put into the IN() clause.
One solution I have found is to put all of the IDs into a temp table with an auto incrementing field which is then joined into the second query.
Is there a better option?
Note: As the first query is run "by the user" and the second is run in a background process, there is no way to combine the 2 into 1 query using sub queries.
I am using MySQL, but I'm thinking it might be useful to have it noted what options there are for other DBs as well.
Use MySQL's FIELD() function:
SELECT name, description, ...
FROM ...
WHERE id IN([ids, any order])
ORDER BY FIELD(id, [ids in order])
FIELD() will return the index of the first parameter that is equal to the first parameter (other than the first parameter itself).
FIELD('a', 'a', 'b', 'c')
will return 1
FIELD('a', 'c', 'b', 'a')
will return 3
This will do exactly what you want if you paste the ids into the IN() clause and the FIELD() function in the same order.
See following how to get sorted data.
SELECT ...
FROM ...
WHERE zip IN (91709,92886,92807,...,91356)
AND user.status=1
ORDER
BY provider.package_id DESC
, FIELD(zip,91709,92886,92807,...,91356)
LIMIT 10
Two solutions that spring to mind:
order by case id when 123 then 1 when 456 then 2 else null end asc
order by instr(','||id||',',',123,456,') asc
(instr() is from Oracle; maybe you have locate() or charindex() or something like that)
If you want to do arbitrary sorting on a query using values inputted by the query in MS SQL Server 2008+, it can be done by creating a table on the fly and doing a join like so (using nomenclature from OP).
SELECT table1.name, table1.description ...
FROM (VALUES (id1,1), (id2,2), (id3,3) ...) AS orderTbl(orderKey, orderIdx)
LEFT JOIN table1 ON orderTbl.orderKey=table1.id
ORDER BY orderTbl.orderIdx
If you replace the VALUES statement with something else that does the same thing, but in ANSI SQL, then this should work on any SQL database.
Note:
The second column in the created table (orderTbl.orderIdx) is necessary when querying record sets larger than 100 or so. I originally didn't have an orderIdx column, but found that with result sets larger than 100 I had to explicitly sort by that column; in SQL Server Express 2014 anyways.
SELECT ORDER_NO, DELIVERY_ADDRESS
from IFSAPP.PURCHASE_ORDER_TAB
where ORDER_NO in ('52000077','52000079','52000167','52000297','52000204','52000409','52000126')
ORDER BY instr('52000077,52000079,52000167,52000297,52000204,52000409,52000126',ORDER_NO)
worked really great
Ans to get sorted data.
SELECT ...
FROM ...
ORDER BY FIELD(user_id,5,3,2,...,50) LIMIT 10
The IN clause describes a set of values, and sets do not have order.
Your solution with a join and then ordering on the display_order column is the most nearly correct solution; anything else is probably a DBMS-specific hack (or is doing some stuff with the OLAP functions in standard SQL). Certainly, the join is the most nearly portable solution (though generating the data with the display_order values may be problematic). Note that you may need to select the ordering columns; that used to be a requirement in standard SQL, though I believe it was relaxed as a rule a while ago (maybe as long ago as SQL-92).
Use MySQL FIND_IN_SET function:
SELECT *
FROM table_name
WHERE id IN (..,..,..,..)
ORDER BY FIND_IN_SET (coloumn_name, .., .., ..);
For Oracle, John's solution using instr() function works. Here's slightly different solution that worked -
SELECT id
FROM table1
WHERE id IN (1, 20, 45, 60)
ORDER BY instr('1, 20, 45, 60', id)
I just tried to do this is MS SQL Server where we do not have FIELD():
SELECT table1.id
...
INNER JOIN
(VALUES (10,1),(3,2),(4,3),(5,4),(7,5),(8,6),(9,7),(2,8),(6,9),(5,10)
) AS X(id,sortorder)
ON X.id = table1.id
ORDER BY X.sortorder
Note that I am allowing duplication too.
Give this a shot:
SELECT name, description, ...
WHERE id IN
(SELECT id FROM table1 WHERE...)
ORDER BY
(SELECT display_order FROM table1 WHERE...),
(SELECT name FROM table1 WHERE...)
The WHEREs will probably take a little tweaking to get the correlated subqueries working properly, but the basic principle should be sound.
My first thought was to write a single query, but you said that was not possible because one is run by the user and the other is run in the background. How are you storing the list of ids to pass from the user to the background process? Why not put them in a temporary table with a column to signify the order.
So how about this:
The user interface bit runs and inserts values into a new table you create. It would insert the id, position and some sort of job number identifier)
The job number is passed to the background process (instead of all the ids)
The background process does a select from the table in step 1 and you join in to get the other information that you require. It uses the job number in the WHERE clause and orders by the position column.
The background process, when finished, deletes from the table based on the job identifier.
I think you should manage to store your data in a way that you will simply do a join and it will be perfect, so no hacks and complicated things going on.
I have for instance a "Recently played" list of track ids, on SQLite i simply do:
SELECT * FROM recently NATURAL JOIN tracks;

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".

Select Mulitple Records based on One record's column value

I have a table which contains related records (multiple revisions of the same record). Each record has a string field that resembles a date (date, time, and microtime). I want to select all records that are older than a specific date. If a record has a related record newer than the specific date, I do not want to select any of those related records. Any ideas for that select statement? Eventually, it will be a REMOVE statement.
Edit: Some Sample Rows
id shared_id date type other_data...
1 2 2010-01-01 01:02:03.1234567 original ...
2 3 2010-01-15 11:12:03.1234733 original ...
3 2 2010-02-01 03:04:04.5465654 amendment ...
If my cut-off date was "2010-01-31", I would want to select id #2 only because id #1 has an amendment newer than the cut-off date.
I found this link helping me generate the select statement.
SELECT DISTINCT T.shared_id,T.date,T.id
FROM table T WHERE T.date = (
SELECT MAX( date ) FROM table WHERE shared_id = T.shared_id )
AND T.date < 'my_cut_off_date_string'
This seems to work for me. Thanks for everyone's help.
Maybe you can try the DATEDIFF() function, check this out:
Link 1
Or this one: Link 2
Or maybe you can try the classic query (SELECT FROM table WHERE data <= anotherdata), but in this case you need to convert both data in timestamp format
DELETE from tablename where relatedField = 'relatedValue' AND dateField <= dateToDeleteFrom
Something along those lines should do what you need it to do, if I understand your scenario. If you provide a sample data set I can adjust the statement to more accurately represent your need, but I think this is a good starting point.
HTH,
Jc

Categories