So i have a table called Ronde:
ID | Teamid | Timestamp
----------------------------------------
1 | 1 | 2013-06-28 18:35:28
2 | 1 | 2013-06-28 18:36:28
3 | 2 | 2013-06-28 18:36:30
4 | 3 | 2013-06-28 18:37:28
5 | 2 | 2013-06-28 18:40:28
6 | 1 | 2013-06-28 18:42:28
7 | 2 | 2013-06-28 18:43:28
8 | 3 | 2013-06-28 18:48:28
Here's a sqlfiddle of same.
So what i need is a query who takes the 2 newest records grouped by Teamid and do a math function with timestamp.
So example:
newest1, newest2
result = ( 60 minutes / (newest2.timestamp - newest1.timestamp) ) * 6
The result is the avg speed between 2 timestamps.
`LIMIT` in subquery don't work
Someone have a solution for my problem ???
Desired output data :
Teamid | Speed
1 | 60
2 | 120
3 | 32,72
Maybe something like this....
http://www.sqlfiddle.com/#!2/2dc3f/7
?
Related
I have a MySQL table that tracks certain totals by both hour of the day and various locations. I am trying to create a query that will total not only each column, but also each row. The query I have so far totals each column, but I can't figure out how to get a total for each row as well.
This is my query:
SELECT * FROM
(SELECT IFNULL(hour,"Total") as hour, SUM(location1), SUM(location2), SUM(location3), SUM(location4), SUM(location), FROM counts WHERE ay = 'AY1617' GROUP BY hour WITH ROLLUP) as crossdata
ORDER BY FIELD (hour,'8:00am','9:00am','10:00am','11:00am','12:00pm','1:00pm','2:00pm','3:00pm','4:00pm','5:00pm','6:00pm','7:00pm','8:00pm','9:00pm','10:00pm','11:00pm')
This is ultimately what I want the output to look like:
hour location1 location2 location3 location4 totals
8am 4 3 2 1 10
9am 1 2 2 1 6
10am 2 3 2 3 10
totals 7 8 6 5 26
How can I achieve this?
For what it's worth, this is not a crosstab query. You aren't pivoting rows to columns.
I tried this query and got the result you want:
SELECT IFNULL(hour, 'Total') AS hour,
SUM(location1) AS location1,
SUM(location2) AS location2,
SUM(location3) AS location3,
SUM(location4) AS location4,
SUM(location1)+SUM(location2)+SUM(location3)+SUM(location4) AS totals
FROM counts
WHERE ay = 'AY1617'
GROUP BY hour WITH ROLLUP;
You should really use the TIME data type instead of strings for the hour. Then it just sorts correctly.
+----------+-----------+-----------+-----------+-----------+--------+
| hourt | location1 | location2 | location3 | location4 | totals |
+----------+-----------+-----------+-----------+-----------+--------+
| 08:00:00 | 4 | 3 | 2 | 1 | 10 |
| 09:00:00 | 1 | 2 | 2 | 1 | 6 |
| 10:00:00 | 2 | 3 | 2 | 3 | 10 |
| Total | 7 | 8 | 6 | 5 | 26 |
+----------+-----------+-----------+-----------+-----------+--------+
i've a little big puzzle here :)
i've a database with 2 tables: survey_reply and questions,
like this:
table SURVEY_REPLY
id | question_id | data_time | user_id | user reply and others col...
--------------------------------------------------------
522| 2 | 2016-02-29 10:07:10 | jacky
. | 3 | 2016-02-29 10:07:22 | jacky
. | 1 | 2016-02-29 10:07:59 | jacky
.. | 4 | 2016-02-29 10:08:40 | jacky
...| 2 | 2016-02-29 11:21:10 | paul
. | 3 | 2016-02-29 11:21:32 | paul
. | 2 | 2016-02-29 11:21:35 | louise
. | 1 | 2016-02-29 11:21:50 | paul
.. | 4 | 2016-02-29 11:22:30 | paul
.. | 3 | 2016-02-29 11:23:01 | louise
The question are shown to the users following the order in this table:
table QUESTIONS
id | q_ord | survey_id | other columns....
-------------------------------------------
1 | 3 | 786
2 | 1 | 786
3 | 2 | 786
4 | 4 | 786
i would know the average reply time, the time spent by people for make his choice and reply to question.
calculation in this example
4th-3th. (last one minus the previus one)
for reply to question.id=4 (question.q_ord=4)
jacky spent 41 sec (10:08:40-10:07:59)
paul 80 sec (11:22:30-11:21:50)
louise doesnt reply
3th-2nd. (3th one minus the 2nd one)
for the question.id=1 (question.q_ord=3)
jacky spent 37 sec (10:07:59-10:07:22)
paul 18 sec (11:21:50-11:21:32)
louise doesnt reply
2nd-1st.
for the question.id=3 (question.q_ord=2)
jacky spent 12 sec (10:07:22-10:07:10)
paul 22 sec (11:21:32-11:21:10)
louise 86 sec (11:23:01-11:21:35)
i dont need to calculate time for the beginning question.id=2 (question.q_ord=1)
the results should be:
q_id | q_ord | av_reply_time
-------------------------------------------
3 | 2 | (12+22+86)/3
1 | 3 | (37+18)/2
4 | 4 | (41+80)/2
how to figure it out?
PS q_ord it's a consecutive integer numbers without skip any number.
Always begins with 1. I always know the maximum number (total question on the survey) in this case just 4.
I'm assuming that your result set is slightly off, and I can't (yet) see the significance of the second table...
SELECT question_id
, AVG(diff) avg_diff
FROM
( SELECT x.user_id
, x.question_id
, TIME_TO_SEC(TIMEDIFF(MAX(y.data_time),x.data_time)) diff
FROM survey_reply x
JOIN survey_reply y
ON y.user_id = x.user_id
AND y.data_time < x.data_time
GROUP
BY x.user_id
, x.question_id
) a
GROUP
BY question_id;
i've 2 tables with date, in timestamp format,
i have to count how many record there are every week in total...
...and have the result in just one query...
so i'll explain it better with examples:
2 table, the first one:
table name: visitor
ID | time | ref (now i put in fake timestamp in time column sorry)
--------------------
1 | 3455 | john
2 | 3566 | ted (week 40)
3 | 8353 | ted (week 38)
4 | 6673 | katy
5 | 6365 | ted (week 40)
6 | 4444 | john
7 | 3555 | ted (week 40)
and the second one (very similar):
table name: users
ID | time | ref (now i put in fake timestamp in time column sorry)
--------------------
1 | 3455 | ted (week 41)
2 | 3566 | ted (week 42)
3 | 8353 | ted (week 40)
4 | 6673 | katy
5 | 6365 | ted (week 41)
6 | 4444 | john
7 | 3555 | ted (week 38)
8 | 6789 | ted (week 43)
i do this query and i obtain this result:
SELECT WEEK(FROM_UNIXTIME(time)) AS week, COUNT( * ) AS tot
FROM visitor WHERE ref='ted' GROUP BY week
table result #1
week | tot
----------
38 | 1
40 | 3
43 | 1
the i do the some for the second table:
SELECT WEEK(FROM_UNIXTIME(time)) AS week, COUNT( * ) AS totuser
FROM users WHERE ref='ted' GROUP BY week
table result #2
week | totuser
----------
38 | 1
40 | 1
41 | 2
42 | 1
but i want with just one query do this result:
week | tot | totusers
---------------------- (when both are 0 doent appear -like 39 for example-)
38 | 1 | 1
40 | 3 | 1
41 | 0 | 2
42 | 0 | 1
43 | 1 | 0
i know that i've to use LEFT JOIN, GROUP BY and IFNULL but i'm doing always something wrong and i cant figure it out.
order by WEEK desc
thank u for any help.
Technically, what you want is a full outer join, but MySQL does not support that. I approach this using union all and group by:
SELECT weeek, SUM(visitors) as visitors, SUM(users) as users
FROM ((SELECT WEEK(FROM_UNIXTIME(time)) AS week, COUNT( * ) AS visitors, 0 as users
FROM visitor
WHERE ref='ted'
GROUP BY week
) UNION ALL
(SELECT WEEK(FROM_UNIXTIME(time)) AS week, 0, COUNT( * )
FROM users
WHERE ref ='ted'
GROUP BY week
)
) w
GROUP BY week
ORDER BY week;
Note: As in your data, this will only include weeks that have either visitors or users. If you want weeks with neither, it is best to start with a table containing all the weeks you want (some sort of calendar table).
I have a table INVENTORY which consists of inventory items. I have the following table structure:
INSTALLATION_ID
COMPONENT_ID
HISTORY_ID
ON_STOCK
LAST_CHANGE
I need to obtain the row with the max HISTORY ID for records for which the spcified LAST_CHANGE month doesn't exist.
Each COMPONENT_ID and INSTALLATION_ID can occur multiple times, they are distinguished by their respective HISTORY_ID
Example:
I have the following records
COMPONENT_ID | INSTALLATION_ID | HISTORY_ID | LAST_CHANGE
1 | 100 | 1 | 2013-01-02
1 | 100 | 2 | 2013-02-01
1 | 100 | 3 | 2013-04-09
2 | 100 | 1 | 2013-02-22
2 | 100 | 2 | 2013-03-12
2 | 100 | 3 | 2013-07-07
2 | 100 | 4 | 2013-08-11
2 | 100 | 5 | 2013-09-15
2 | 100 | 6 | 2013-09-29
3 | 100 | 1 | 2013-02-14
3 | 100 | 2 | 2013-09-23
4 | 100 | 1 | 2013-04-17
I am now trying to retrieve the rows with the max HISTORY ID for each component but ONLY for COMPONENT_IDs in which the specifiec month does not exists
I have tried the following:
SELECT
INVENTORY.COMPONENT_ID,
INVENTORY.HISTORY_ID
FROM INVENTORY
WHERE INVENTORY.HISTORY_ID = (SELECT
MAX(t2.HISTORY_ID)
FROM INVENTORY t2
WHERE NOT EXISTS
(
SELECT *
FROM INVENTORY t3
WHERE MONTH(t3.LAST_CHANGE) = 9
AND YEAR(t3.LAST_CHANGE)= 2013
AND t3.HISTORY_ID = t2.HISTORY_ID
)
)
AND INVENTORY.INSTALLATION_ID = 200
AND YEAR(INVENTORY.LAST_CHANGE) = 2013
The query seems to have correct syntax but it times out.
In this particular case, i would like to retrieve the maximum HISTORY_ID for all components except for those that have records in September.
Because I need to completely exclude rows by their month, i cannot use NOT IN, since they will just suppress the records for september but the same component could show up with another month.
Could anybody give some pointers? Thanks a lot.
If I understand correctly what you want you can do it like this
SELECT component_id, MAX(history_id) history_id
FROM inventory
WHERE last_change BETWEEN '2013-01-01' AND '2013-12-31'
AND installation_id = 100
GROUP BY component_id
HAVING MAX(MONTH(last_change) = 9) = 0
Output:
| COMPONENT_ID | HISTORY_ID |
|--------------|------------|
| 1 | 3 |
| 4 | 1 |
If you always filter by installation_id and a year of last_change make sure that you have a compound index on (installation_id, last_change)
ALTER TABLE inventory ADD INDEX (installation_id, last_change);
Here is SQLFiddle demo
I have MYSQL data like this
id | number
1 | 3
4 | 4
7 | 7
10 | 5
11 | 6
I have the database like that, and how to update the number so it will be sorted incremental?
Which mean the result will be like this
id | number
1 | 1
4 | 2
7 | 3
10 | 4
11 | 5
i updated the question so there will be no confusion in id and since id will be not consecutive
set #val = 0;
update table_name set number = (#val:=#val+1);
This would work even if table is:
id | number
1 | 3
4 | 4
7 | NULL
10 | 5
11 | NULL
to be like this:
id | number
1 | 1
4 | 2
7 | 3
10 | 4
11 | 5
update table set number=id where 1
Try this:
SET #idrank = 0;
SET #numrank = 0;
UPDATE
tbl a
INNER JOIN
(
SELECT id, #idrank:=#idrank+1 AS id_rank
FROM tbl
ORDER BY id
) b ON a.id = b.id
INNER JOIN
(
SELECT number, #numrank:=#numrank+1 AS number_rank
FROM tbl
ORDER BY number
) c ON b.id_rank = c.number_rank
SET
a.number = c.number;
This will account for gaps and irregularities in the number field as well as duplicates. Say the entire data set was something like:
id | number
---------------
2 | 534
3 | 421
6 | 2038
7 | 41
10 | 5383
11 | 5
12 | 933
15 | 43
The resulting table set after the update will be:
id | number
---------------
2 | 5
3 | 41
6 | 43
7 | 421
10 | 534
11 | 933
12 | 2038
15 | 5383
Explanation:
It basically takes the ascending ranks of each field separately and joins on the ranks so that the ordered id is matched up with corresponding ordered number.
The first INNER JOIN subselect will look like this:
id | id_rank
---------------
2 | 1
3 | 2
6 | 3
7 | 4
10 | 5
11 | 6
12 | 7
15 | 8
Then the second INNER JOIN subselect will like this:
number | number_rank
---------------
534 | 5
421 | 4
2038 | 7
41 | 2
5383 | 8
5 | 1
933 | 6
43 | 3
Then when you join the two subselects on id_rank = number_rank, you line the ascending order of the two fields up. Once you have that, updating becomes a simple matter of setting the table's number = the second joined table's number.