Mysql select UNIQUE row on column - php

I have a table as following:(Ex)
id | vid | time
------------------------
1 | 4 | 1333635317
2 | 4 | 1333635323
3 | 2 | 1333635336
4 | 4 | 1333635343
5 | 5 | 1333635349
I want to be just a row (the last row [ID: 4]) of the same rows[id:1,2,4], how it will output the query?
I mean, as a result of these:
id | vid | time
------------------------
3 | 2 | 1333635336
4 | 4 | 1333635343
5 | 5 | 1333635349
What do i do?
i trying it as:
SELECT * from tbale as t1 where vid = 4 GROUP BY vid ORDER BY id DESC
but doesn't work ORDER BY in my query.

Get the max time per vid and use in to get those rows from the table.
select * from tablename
where (vid,time) in (select vid,max(time)
from tablename
group by vid)
order by id

Related

Get neighboring rows (2 above and 2 below) of a certain row in PHP while loop

I have a table like so (after doing a query on it to order it by score):
+---+-------+------+
|id | level |score |
+---+-------+------+
| 4 | 1 | 30 |
| 3 | 1 | 35 |
| 1 | 1 | 40 |
| 5 | 1 | 45 |
| 7 | 1 | 50 |
| 8 | 1 | 55 |
+---+-------+------+
I will output that to php in a while loop. So each row in the while loop will be the same as in the table above.
Essentially what I want to do is show 5 of these rows in a table (in html), with a certain row (e.g. where id=5) in the middle and have the two rows above and below it (in the correct order). This will be like a score board but only showing the user's score with the two above and two below.
E.g. say the user is id=5, I want to show
+---+-------+------+
|id | level |score |
+---+-------+------+
| 3 | 1 | 35 |
| 1 | 1 | 40 |
| 5 | 1 | 45 |
| 7 | 1 | 50 |
| 8 | 1 | 55 |
I am wondering does anyone know a way of doing this in php?
Basically
//select query output is in while loop
//get a certain row of the loop
//get the two rows above it and two rows below it
One method uses a lot of variables:
select t.*
from (select t.*,
lag(id, 1) over (order by score) as prev_id,
lag(id, 2) over (order by score) as prev_id2,
lead(id, 1) over (order by score) as next_id,
lead(id, 2) over (order by score) as next_id2
from t
) t
where 5 in (prev_id, prev_id2, next_id, next_id2, id)
order by score;
An alternative method is something like this:
(select t.*
from t
where t.score <= (select t2.score from t t2 where t2.id = 5)
order by score desc
limit 3
) union all
(select t.*
from t
where t.score > (select t2.score from t t2 where t2.id = 5)
order by score
limit 2
)
order by score;
This exactly syntax may not work in all databases, but the idea can easily be translated in whatever dialect of SQL. This also assumes that the scores are unique.

Count integer value and order by user

So my table looks like this:
| id | user | points |
| 1 | Sam | 1 |
| 2 | Sam | 6 |
| 3 | Phil | 1 |
The query I am currently using is:
SELECT user,COUNT(*) FROM table GROUP BY user order by COUNT(*) DESC
This returns the current value:
Sam: 2
Phil: 1
It looks like it counts the number of rows, not the total points? How can I do this?
The correct return should be Sam: 7.
Use SUM instead of COUNT
SELECT user, SUM(points) FROM table GROUP BY user

SQL query to return combined data of all rows that don't belong to current user

Imagine this is my table:
----------------------------------------------------
| id | user_id | amount_1 | amount_2 | amount_3 |
----------------------------------------------------
| 1 | 1 | 2 | 3 | 4 |
----------------------------------------------------
| 2 | 2 | 2 | 1 | 1 |
----------------------------------------------------
| 3 | 2 | 1 | 2 | 2 |
----------------------------------------------------
| 4 | 3 | 2 | 1 | 4 |
----------------------------------------------------
I need a query that gives me one result set for every entry that belongs to my current user, and then returns everything else as a single combined row with the amounts summed.
So in this case if I am user 1, I should get the following rows back:
---------------------------------------
| id | amount_1 | amount_2 | amount_3 |
---------------------------------------
| 1 | 2 | 3 | 4 | my own amounts
---------------------------------------
| 2 | 5 | 4 | 7 | everyone else's amounts
---------------------------------------
Any tips?
I've considered it might be a better idea to just filter the data in the code (php). Please help i'm starting to hate myself
You could use a UNION in sql
select 1 id, amount_1, amount_2, amount_3
from my_table
where user_id = 1
union
select 2 , sum(amount_1) , sum(amount_2), sum(amount_3 )
from my_table
where user_id <> 1
You can do with one query using union:
SELECT user_id, amount_1, amount_2, amount_3
FROM table
WHERE user_id = YOUR_USER_ID
UNION
SELECT -1, SUM(amount_1) AS amount_1, SUM(amount_2) AS amount_2, SUM(amount_3) AS amount_3
FROM table
WHERE user_id != YOUR_USER_ID
You can use aggregation in one fell swoop:
select (case when user_id = 1 then id end) as my_user_or_not,
sum(amount_1), sum(amount_2), sum(amount_3)
from t
group by my_user_or_not;
The null values in the first column indicate another user. You have labelled the column id, which is a bit problematic if you were -- for instance -- to choose user_id = 2 in your example. NULL seems safer for this purpose.

Mysql max function with specific value

I have following table structure for tTable
id | version | parentId
1 | 1 | 1
2 | 1 | 2
3 | 2 | 2
4 | 1 | 3
5 | 2 | 3
6 | 3 | 3
If I execute
SELECT MAX(id) AS maxId, FROM tTable GROUP BY parentId
then it will return below result.
id | version | parentId
1 | 1 | 1
3 | 2 | 2
6 | 3 | 3
But here I would like to a little change in returned result for example I would like to have following result set with max() in tTable.
id | version | parentId
1 | 1 | 1
3 | 2 | 2
*5 | 2 | 3*
id = 5th record. I would like to get other two records with max(id) but want to get different id (I want to provide condition) for parentId = 3.
Is it possible in max() with any condition. I would like to preserve other max id but want only change in specific record?
Edit:
Here 5 (or may be 4) will be coming from dynamic variable. So in case of parentId = 3 there could be any value for id (may be 4 or 5 or 6).
You can use UNION ALL to get the result you want but that may not be a exact solution. thought of putting it once if it helps. See a demo here http://sqlfiddle.com/#!2/78cde/9
(SELECT MAX(id) AS maxId, version, parentId
FROM tTable
WHERE parentId != 3
GROUP BY parentId)
union all
(SELECT id as maxId, version, parentId
FROM tTable
WHERE parentId = 3
order by maxId desc
limit 1,1)

reduction of each row in the table of database

i have a table temporary as follow as:
student | Data | number
-----------|---------------|--------------
1 | book | 2
1 | book | 5
1 | book | 9
2 | book | 1
2 | book | 5
i will show reduction of column in like as output column as follow as:
student | Data | number |output (number column of next row-previous line )
-----------|---------------|----------------|--------------
1 | book | 2 | 0
1 | book | 5 | 3 (result of (5-2=3)
1 | book | 9 | 4 (result of (9-5=4)
2 | book | 1 | 0
2 | book | 5 | 4 (result of (5-1=4)
how are writing of php's script is correct? because i'm confused
You didn't mention your DBMS, so this is standard SQL:
select student,
data,
number,
number - lag(number,1,number) over (partition by student order by id) as output
from the_table
order by student, id
SQLFiddle example
The following script will subtract the number from previous number for the same student. Here's how you can do it in MySQL (which doesn't support window functions.)
SELECT
t1.student,
t1.Data,
t1.number,
IF (t2.number IS NULL, 0, t1.number - MAX(t2.number)) as output
FROM
tbl t1
LEFT JOIN
tbl t2
ON
t1.student = t2.student
AND t1.number > t2.number
GROUP BY
t1.student, t1.Data, t1.number
Here's the SQL Fiddle

Categories