Is it possible to get random items inside the same day?
For example:
+----+---------------------+
| id | md |
+----+---------------------+
| 1 | 2010-06-27 11:26:01 |
| 2 | 2010-06-27 11:28:20 |
| 3 | 2010-06-27 11:29:46 |
| 4 | 2010-06-27 11:30:50 |
| 5 | 2010-06-27 12:20:56 |
| 6 | 2010-06-27 12:27:42 |
| 7 | 2010-06-27 15:14:05 |
| 8 | 2010-07-06 01:53:33 |
| 9 | 2010-07-06 01:52:52 |
+----+---------------------+
I want to pick random items inside the same day, but at same time i want it ordered by date desc. Something like this:
+----+---------------------+
| id | md |
+----+---------------------+
| 8 | 2010-07-06 01:53:33 | random block
| 9 | 2010-07-06 01:52:52 |
| 2 | 2010-06-27 11:28:20 | random block
| 4 | 2010-06-27 11:30:50 |
| 1 | 2010-06-27 11:26:01 |
| 6 | 2010-06-27 12:27:42 |
| 3 | 2010-06-27 11:29:46 |
| 5 | 2010-06-27 12:20:56 |
| 7 | 2010-06-27 15:14:05 |
+----+---------------------+
No idea how to start or if this is even possible since order by rand() won't accept grouping.
really simple:
SELECT *
FROM tbl
ORDER BY md DESC, RAND()
Probably not very efficient, but try
select * from (select * from tbl order by rand()) as t group by date(md)
If I have understood your question correctly, this should do the trick:
SELECT * FROM table1 ORDER BY DATE(md) DESC, RAND();
Example:
DROP TABLE IF EXISTS `table1`;
CREATE TABLE `table1` (
`id` int(11) NOT NULL auto_increment,
`md` DATETIME,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
DELIMITER //
DROP PROCEDURE IF EXISTS autofill//
CREATE PROCEDURE autofill()
BEGIN
DECLARE i INT DEFAULT 0;
WHILE i < 50 DO
INSERT INTO table1 (md) VALUES (DATE_ADD(NOW(), INTERVAL FLOOR(RAND() * 1000) HOUR));
SET i = i + 1;
END WHILE;
END;
//
DELIMITER ;
CALL autofill();
SELECT * FROM table1 ORDER BY DATE(md) DESC, RAND();
+----+---------------------+
| id | md |
+----+---------------------+
| 8 | 2010-08-16 13:46:04 |
| 16 | 2010-08-15 19:46:05 |
| 47 | 2010-08-15 18:46:06 |
| 25 | 2010-08-15 15:46:05 |
| 33 | 2010-08-15 09:46:05 |
| 3 | 2010-08-14 20:46:04 |
| 45 | 2010-08-13 03:46:06 |
| 17 | 2010-08-12 13:46:05 |
| 12 | 2010-08-12 06:46:05 |
| 7 | 2010-08-12 15:46:04 |
| 37 | 2010-08-12 14:46:05 |
| 40 | 2010-08-10 05:46:06 |
| 13 | 2010-08-09 10:46:05 |
| 4 | 2010-08-09 00:46:04 |
| 1 | 2010-08-06 12:46:04 |
| 28 | 2010-08-02 23:46:05 |
| 15 | 2010-08-02 10:46:05 |
| 2 | 2010-08-02 01:46:04 |
| 38 | 2010-07-31 13:46:06 |
| 27 | 2010-07-31 04:46:05 |
| 30 | 2010-07-31 03:46:05 |
| 22 | 2010-07-31 08:46:05 |
| 50 | 2010-07-30 05:46:06 |
| 11 | 2010-07-28 13:46:05 |
| 18 | 2010-07-28 21:46:05 |
| 29 | 2010-07-27 23:46:05 |
| 35 | 2010-07-27 11:46:05 |
| 6 | 2010-07-26 20:46:04 |
| 20 | 2010-07-25 03:46:05 |
| 31 | 2010-07-23 07:46:05 |
| 14 | 2010-07-23 23:46:05 |
| 23 | 2010-07-23 10:46:05 |
| 48 | 2010-07-23 17:46:06 |
| 42 | 2010-07-21 03:46:06 |
| 39 | 2010-07-20 05:46:06 |
| 36 | 2010-07-18 05:46:05 |
| 10 | 2010-07-17 01:46:05 |
| 32 | 2010-07-16 06:46:05 |
| 9 | 2010-07-16 15:46:04 |
| 24 | 2010-07-16 10:46:05 |
| 43 | 2010-07-16 09:46:06 |
| 5 | 2010-07-14 01:46:04 |
| 21 | 2010-07-14 08:46:05 |
| 49 | 2010-07-13 07:46:06 |
| 41 | 2010-07-13 15:46:06 |
| 46 | 2010-07-12 04:46:06 |
| 44 | 2010-07-11 16:46:06 |
| 26 | 2010-07-10 14:46:05 |
| 34 | 2010-07-09 16:46:05 |
| 19 | 2010-07-07 01:46:05 |
+----+---------------------+
You can use a WHERE clause...
WHERE date = 'insert date' ORDER BY rand() LIMIT 1`
Then just use PHP to insert whatever the date is into the string there for each date.
Or to use only one MySQL query, simply order them by date descending and pull them all out using PHP...
while ($item = mysql_fetch_array($query)):
// process to figure out the date (I'm sure you can do that)
$mydates[$date][] = $id; // add that ID to that date array
endwhile;
foreach ($mydates as $date):
$key = array_rand($date);
endforeach;
Related
in my table https://www.db-fiddle.com/f/4yPorU6k3SjQ5nmhgi1wGo/0
i use query
SELECT id
FROM test
ORDER BY id <= 7 DESC, id DESC
i want to order everything from 7 to lesser by the bigger then everything else by the lesser
my query give me
| id |
| --- |
| 6 |
| 3 |
| 2 |
| 1 |
| 65 |
| 35 |
| 34 |
| 33 |
| 12 |
| 11 |
| 11 |
| 10 |
but i want to give me
| id |
| --- |
| 6 |
| 3 |
| 2 |
| 1 |
| 10 |
| 11 |
| 11 |
| 12 |
| 33 |
| 34 |
| 35 |
| 65 |
Consider a conditional sort, like so:
select id
from test
order by
case when id <= 7 then id end desc,
id
Demo on DB Fiddle:
| id |
| -: |
| 6 |
| 3 |
| 2 |
| 1 |
| 10 |
| 11 |
| 11 |
| 12 |
| 33 |
| 34 |
| 35 |
| 65 |
I think you want:
SELECT id
FROM test
ORDER BY id <= 7 DESC,
(CASE WHEN id <= 7 THEN id END) DESC,
id ASC
I have a select taht brings the result like this:
+-----------+------------+--------------+
| parking_id| start_time | end_time |
+-----------+------------+--------------+
| 38 | 09:15:00 | 10:32:00 |
| 57 | 11:45:00 | 13:21:00 |
| 33 | 14:40:00 | 16:35:00 |
| 15 | 17:13:00 | 19:15:00 |
| 68 | 20:54:00 | NULL |
+-----------+------------+--------------+
As you can see the IDs dont follow a linear order, but wat i really need is a select that brings me the time between the new start_time and end_time for the last inserted , that follows this non linear order, so i need a select that brings me this:
+-----------+------------+--------------+----------------+
| parking_id| start_time | end_time | time_btw_parks |
+-----------+------------+--------------+----------------+
| 38 | 09:15:00 | 10:32:00 | NULL |
| 57 | 11:45:00 | 13:21:00 | 01:13:00 |
| 33 | 14:40:00 | 16:35:00 | 01:19:00 |
| 15 | 17:13:00 | 19:15:00 | 00:38:00 |
| 68 | 20:54:00 | NULL | 01:39:00 |
+-----------+------------+--------------+----------------+
Doesn't have to necessary be select query. Anything that solves it would help.
For this sample data you can use timediff() function:
select t.parking_id, t.start_time, t.end_time,
timediff(t.start_time, max(tt.end_time)) time_btw_parks
from tablename t left join tablename tt
on t.start_time > tt.end_time
group by t.parking_id, t.start_time, t.end_time
order by t.start_time
See the demo.
Results:
| parking_id | start_time | end_time | time_btw_parks |
| ---------- | ---------- | -------- | -------------- |
| 38 | 09:15:00 | 10:32:00 | |
| 57 | 11:45:00 | 13:21:00 | 01:13:00 |
| 33 | 14:40:00 | 16:35:00 | 01:19:00 |
| 15 | 17:13:00 | 19:15:00 | 00:38:00 |
| 68 | 20:54:00 | | 01:39:00 |
I want to copy a specific row from tables temperature, rules and schedule to stats table.
In temperature table, I want the latest temperature which is 18.6
mysql> SELECT * FROM currenttemp ORDER BY `timestamp` DESC limit 10 ;
+---------------------+-----------------+-------------+----------+----------+
| timestamp | sensor | currenttemp | humidity | pressure |
+---------------------+-----------------+-------------+----------+----------+
| 2017-03-25 15:28:03 | sensor-1stFloor | 18.6 | 49.85 | 1021.26 |
| 2017-03-25 15:27:03 | sensor-1stFloor | 18.7 | 49.81 | 1021.26 |
| 2017-03-25 15:26:03 | sensor-1stFloor | 18.8 | 49.82 | 1021.26 |
| 2017-03-25 15:25:03 | sensor-1stFloor | 18.9 | 49.85 | 1021.22 |
| 2017-03-25 15:24:03 | sensor-1stFloor | 18.99 | 49.83 | 1021.21 |
| 2017-03-25 15:23:03 | sensor-1stFloor | 18.61 | 49.85 | 1021.18 |
| 2017-03-25 15:22:02 | sensor-1stFloor | 18.62 | 49.8 | 1021.3 |
| 2017-03-25 15:21:02 | sensor-1stFloor | 18.63 | 49.82 | 1021.39 |
| 2017-03-25 15:20:03 | sensor-1stFloor | 18.61 | 49.82 | 1021.28 |
| 2017-03-25 15:19:03 | sensor-1stFloor | 18.62 | 49.82 | 1021.37 |
+---------------------+-----------------+-------------+----------+----------+
In rules table, I want the targettemp for schedule 4 which is 40
mysql> SELECT * FROM rules limit 10 ;
+----+----------+--------+------------+
| id | schedule | sensor | targettemp |
+----+----------+--------+------------+
| 1 | 4 | 1 | 40 |
| 2 | 5 | 1 | 5 |
+----+----------+--------+------------+
In schedule table, I want the endtime for id 4 which is 10:00:00
mysql> SELECT * FROM schedules limit 10 ;
+----+--------------+-----------+--------------+-----------+----------+---------+------------+--------+
| id | friendlyname | dayofweek | pretimestart | timestart | endtime | enabled | targettemp | sensor |
+----+--------------+-----------+--------------+-----------+----------+---------+------------+--------+
| 4 | test | 1111110 | 00:00:00 | 00:00:00 | 10:00:00 | 1 | 30 | 1 |
| 5 | sun | 0000001 | 00:00:00 | 00:00:00 | 20:00:00 | 0 | 0 | |
+----+--------------+-----------+--------------+-----------+----------+---------+------------+--------+
I then want to insert these data to the stats table
currenttemp which is 18.6
targettemp for schedule 4 which is 40
endtime for id 4 which is 10:00:00
the timestamp is done automatically
state will be between ON and OFF
please look at the 1st row in stats table as example from the data copied from the above tables.
mysql> SELECT * FROM stats limit 10 ;
+---------------------+-------------+------------+----------+-------+
| timestamp | currenttemp | targettemp | endtime | state |
+---------------------+-------------+------------+----------+-------+
| 2017-03-25 15:41:46 | 18.6 | 40 | 10:00:00 | OFF |
| 2017-03-19 16:53:05 | 16.83 | 5 | 00:00:00 | OFF |
| 2017-03-19 16:54:14 | 16.83 | 40 | 00:00:00 | ON |
| 2017-03-19 20:04:07 | 16.58 | 40 | 00:00:00 | ON |
| 2017-03-19 20:04:15 | 16.58 | 5 | 00:00:00 | OFF |
| 2017-03-19 20:06:29 | 16.58 | 5 | 00:00:00 | OFF |
| 2017-03-19 20:34:28 | 16.54 | 5 | 00:00:00 | OFF |
| 2017-03-19 20:34:56 | 16.54 | 5 | 00:00:00 | OFF |
| 2017-03-19 20:35:26 | 16.54 | 40 | 00:00:00 | ON |
| 2017-03-19 20:38:05 | 16.54 | 40 | 00:00:00 | ON |
+---------------------+-------------+------------+----------+-------+
I will have 2 queries. One with the state OFF and one with the state ON.
Your question is unclear because the relationship between temperature and the other tables is unclear. Let me assume that there is a join key to schedules. If so, the query you want would look something like this:
INSERT INTO stats (currenttemp, targettemp, endtime)
SELECT t.temperature, r.targettemp, s.timeend
FROM schedules s INNER JOIN
rules r
ON s.id = r.schedule INNER JOIN
temperature t
ON t.schedule = s.id
WHERE s.id = 4 AND
t.timestamp = (SELECT MAX(t2.timestamp)
FROM temperature t2
WHERE t2.schedule = t.schedule
);
this seems to work
INSERT INTO stats (currenttemp,targettemp,endtime,state)
SELECT
temperature,r.targettemp,s.timeend,'OFF'
FROM
schedules s
INNER JOIN rules r
ON s.id = r.schedule
INNER JOIN temperature
WHERE timestamp = (SELECT MAX(timestamp) FROM temperature)
AND s.id = 4
i can see now in my stats table
mysql> SELECT * FROM stats limit 10 ;
+---------------------+-------------+------------+----------+-------+
| timestamp | currenttemp | targettemp | endtime | state |
+---------------------+-------------+------------+----------+-------+
| 2017-04-06 17:58:05 | 19.53 | 40 | 10:00:00 | OFF |
+---------------------+-------------+------------+----------+-------+
im new with SQL. i know to how select a list with limit comand. but that way need a value to select. what if i want select a list from random id to the last. exemple:
I want to select a list with id from 4 -> last of row (cuz i dont know whats last id)
select * from thing1 where id>=4 order by rand();
where thing1 is your table name. How you seed your random number generator (RNG) is up to you.
+----+---------+------------+
| id | conn_id | read_date |
+----+---------+------------+
| 11 | 3 | 2013-02-21 |
| 5 | 1 | 2012-02-21 |
| 8 | 5 | 2010-12-21 |
| 15 | 7 | 2019-12-21 |
| 14 | 6 | 2019-12-21 |
| 13 | 5 | 2016-02-21 |
| 4 | 2 | 2010-12-21 |
| 7 | 2 | 2014-02-21 |
| 6 | 2 | 2007-12-21 |
| 12 | 4 | 2014-02-21 |
| 16 | 8 | 2010-12-21 |
| 9 | 3 | 2010-12-21 |
| 10 | 4 | 2010-12-21 |
+----+---------+------------+
13 rows in set (0.14 sec)
mysql> select * from thing1 where id>=4 order by rand();
+----+---------+------------+
| id | conn_id | read_date |
+----+---------+------------+
| 13 | 5 | 2016-02-21 |
| 6 | 2 | 2007-12-21 |
| 10 | 4 | 2010-12-21 |
| 16 | 8 | 2010-12-21 |
| 14 | 6 | 2019-12-21 |
| 5 | 1 | 2012-02-21 |
| 7 | 2 | 2014-02-21 |
| 11 | 3 | 2013-02-21 |
| 12 | 4 | 2014-02-21 |
| 4 | 2 | 2010-12-21 |
| 8 | 5 | 2010-12-21 |
| 9 | 3 | 2010-12-21 |
| 15 | 7 | 2019-12-21 |
+----+---------+------------+
13 rows in set (0.02 sec)
mysql> select * from thing1 where id>=4 order by rand();
+----+---------+------------+
| id | conn_id | read_date |
+----+---------+------------+
| 10 | 4 | 2010-12-21 |
| 4 | 2 | 2010-12-21 |
| 6 | 2 | 2007-12-21 |
| 7 | 2 | 2014-02-21 |
| 5 | 1 | 2012-02-21 |
| 9 | 3 | 2010-12-21 |
| 12 | 4 | 2014-02-21 |
| 16 | 8 | 2010-12-21 |
| 8 | 5 | 2010-12-21 |
| 15 | 7 | 2019-12-21 |
| 13 | 5 | 2016-02-21 |
| 14 | 6 | 2019-12-21 |
| 11 | 3 | 2013-02-21 |
+----+---------+------------+
13 rows in set (0.05 sec)
Stored Proc
To have starting random position, until the end, random ordering
-- drop procedure getRandomStartToEnd;
delimiter $$
create procedure getRandomStartToEnd()
BEGIN
declare theCount int;
declare theStart int;
select count(*) into theCount from thing1;
set #theStart:=floor((rand()*#theCount)+1);
select * from thing1 where id>=#theStart order by rand();
END
$$
call getRandomStartToEnd; -- call stored proc
Given the table below I want to select the rows for which the same 'CODE' is associated with multiple 'SUB_CODE'.
+------+------------+-------------+
| DIV | CODE | SUB_CODE |
+------+------------+-------------+
| 11 | 1000 | 1212 |
| 11 | 1000 | 1213 |
| 11 | 1000 | 3434 |
| 11 | 1000 | 1000 |
| 11 | 1000 | 3000 |
| 11 | 3000 | 1213 |
| 11 | 2000 | 1212 |
| 20 | 1500 | 5656 |
| 20 | 1500 | 1213 |
+------+------------+-------------+
For the above table the result should be
+------+------------+-------------+
| DIV | CODE | SUB_CODE |
+------+------------+-------------+
| 11 | 1000 | 1212 |
| 11 | 1000 | 1213 |
| 11 | 1000 | 3434 |
| 11 | 1000 | 1000 |
| 11 | 1000 | 3000 |
| 11 | 1500 | 5656 |
| 11 | 1500 | 1213 |
+------+------------+-------------+
This is what I tried, how ever my results fails.
Select CODE from TABLE_NAME where (count(SUB_CODE) > 1);
First fetch the CODEs for which multiple SUB_CODEs exists; then project the table columns filtering using the above results as a nested query:
select * from TABLE_NAME where CODE in
(select CODE from TABLE_NAME group by CODE having count(SUB_CODE) > 1);
demo: http://sqlfiddle.com/#!9/1d91f/3/0
TRY THIS:
Select `DIV`, `CODE`, `SUB_CODE` from TABLE_NAME GROUP BY `SUB_CODE`