mysql insert max min value grouped by date - mysql

This is my table schema:
mysql> describe stocks;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| symbol | varchar(32) | NO | | NULL | |
| date | datetime | NO | | NULL | |
| value | float(10,3) | NO | | NULL | |
| contracts | int(8) | NO | | NULL | |
| open | float(10,3) | NO | | NULL | |
| close | float(10,3) | NO | | NULL | |
| high | float(10,3) | NO | | NULL | |
| low | float(10,3) | NO | | NULL | |
+-----------+-------------+------+-----+---------+----------------+
9 rows in set (0.00 sec)
I added two new columns named high and low so they are empty now.
My goal is fill up these columns with the relative max(value),min(value) based on each daytime!
My first insight is this query:
select distinct DATE(date),max(value) as max,min(value) as min from stocks GROUP BY DATE(date);
...
| 2017-02-20 | 19130.000 | 18875.000 |
| 2017-02-21 | 19170.000 | 18780.000 |
| 2017-02-22 | 19125.000 | 18745.000 |
| 2017-02-23 | 18980.000 | 18765.000 |
| 2017-02-24 | 18840.000 | 18505.000 |
+------------+-----------+-----------+
that achieve the first step, now I should join these results with each rows:
| 900363 | FIB7C | 2017-02-20 17:49:44 | 18930.000 | 1 | 0.000 | 0.000 | 0.000 | 0.000 |
and insert the correct value based on DATE(date) but I still not catch to do with INSERT INTO.
Thanks for helps regards.

You can do this with a join in the update along with an aggregation to calculate the values:
update stocks s join
(select date(date) as d, max(value) as dhigh, min(value) as dlow
from stocks s
group by date(date)
) sd
on date(s.date) = sd.d
set s.high = sd.dhigh,
s.low = sd.dlow;

Related

How to show data from sql table to make one of columns value column header(date)

Hello I have 2 tables in mysql DB:
mysql> describe lvlsupdate;
+--------------+-------------+------+-----+-------------------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+-------------------+-------------------+
| LvlsUpdateId | int | NO | PRI | NULL | auto_increment |
| UID | int | NO | MUL | NULL | |
| Nick | varchar(30) | NO | | NULL | |
| date | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
| Lvl | int | YES | | NULL | |
+--------------+-------------+------+-----+-------------------+-------------------+
5 rows in set (0.02 sec)
mysql> describe players;
+--------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+----------------+
| UID | int | NO | PRI | NULL | auto_increment |
| Nick | varchar(30) | NO | UNI | NULL | |
| Active | tinyint(1) | NO | | NULL | |
+--------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
In one of theme there is column date which includes timestamp value.
I'd like to create query that will show me data that there will be column Nick and 7 dates (today and 6 days before). And in each row there should be nick and lvl value from each of this dates in proper column.
For now, I've created query like this:
SELECT LvlsUpdate.nick, LvlsUpdate.lvl, LvlsUpdate.date
FROM LvlsUpdate
INNER JOIN Players ON LvlsUpdate.uid = Players.uid
WHERE Players.active = 1 AND LvlsUpdate.date > date_sub(now(), interval 7 day)
which shows me list of nicks, lvls, and date but there are duplicates of nicks, it looks like this:
+------------------+------+---------------------+
| nick | lvl | date |
+------------------+------+---------------------+
| Player1 | 124 | 2020-10-11 00:01:02 |
| Player1 | 125 | 2020-10-12 00:01:03 |
| Player1 | 125 | 2020-10-13 00:01:02 |
| Player2 | 233 | 2020-10-11 00:01:02 |
| Player2 | 233 | 2020-10-12 00:01:03 |
| Player2 | 233 | 2020-10-13 00:01:02 |
| Player3 | 164 | 2020-10-11 00:01:02 |
| Player3 | 164 | 2020-10-12 00:01:03 |
| etc....
There is reference between LvlsUpdate.UID and Players.UID. There is only 1 entry per player per day.
Is it possible to do it in sql?

Selecting from two different tables and order by for one and limit results of the other?

Please someone help.
I have two tables, car_table and add_table, they are completely different tables.
car_table:
+---------+-------------+------+-----+------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+------------------+----------------+
| id | int(3) | NO | PRI | NULL | auto_increment |
| car | varchar(15) | NO | | NULL | |
| manuf | varchar(10) | NO | | NULL | |
|timestamp| timestamp | NO | | CURRENT_TIMESTAMP| |
+-------+-------------+------+-----+---------+---------------------------+
Sample Data:
+----+--------+-------+-----------+
| id | car | manuf | timestamp |
+----+--------+-------+-----------+
| 1 | M5 | BMW | time |
| 2 | Golf | VW | time |
| 3 | Toyota |pickup | time |
| 4 | Ford | focus | time |
+----+--------+-------+-----------+
add_table
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
|add_id | int(3) | NO | PRI | NULL | auto_increment |
| link | varchar(15) | YES | | NULL | |
| s_img | varchar(10) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
Sample Data:
+-------+--------+-------+
|add_id | link | s_img |
+-------+--------+-------+
| 1 | link | img |
| 2 | link | img |
| 3 | link | img |
| 4 | link | img |
+-------+--------+-------+
I am trying to write a select statement that will order the car_table by timestamp and limit the add_table to 3 results, mixing the results so that a add_table results are separated by car_table results.
Below is what I have so far but not sure where to go from here. (update: this seems to partially work, however not sure what it is ordering the add_table by and not sure if it's even the correct way of doing it.)
SELECT id,car,manuf,timestamp,
FROM car_table
UNION ALL
SELECT add_id,link,s_img,NULL AS timestamp
FROM add_table ORDER BY TimeStamp

MYSQL Select Where Time Between Returns Rows Older Than Query

I have a mysql DB with a table called data,
mysql> describe data;
+-------+---------------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------+------+-----+-------------------+----------------+
| idx | int(11) | NO | PRI | NULL | auto_increment |
| ts | timestamp | NO | | CURRENT_TIMESTAMP | |
| id | tinyint(3) unsigned | NO | | NULL | |
| value | decimal(10,2) | YES | | NULL | |
+-------+---------------------+------+-----+-------------------+----------------+
When I try to select a specific date range, e.g., today, the query returns data that is out of the date range.
mysql> SELECT * FROM data WHERE ts BETWEEN '2016-11-27 00:11:00' AND '2016-11-29 00:11:00' AND id LIKE '0' OR id LIKE '1' ORDER BY ts ASC LIMIT 10;
+-------+---------------------+----+-------+
| idx | ts | id | value |
+-------+---------------------+----+-------+
| 14117 | 2016-11-12 15:24:16 | 1 | 0.00 |
| 20144 | 2016-11-16 20:03:50 | 1 | 56.00 |
| 20147 | 2016-11-16 20:04:10 | 1 | 52.00 |
| 20150 | 2016-11-16 20:05:10 | 1 | 52.00 |
| 20153 | 2016-11-16 20:06:11 | 1 | 52.00 |
| 20156 | 2016-11-16 20:07:11 | 1 | 52.00 |
| 20159 | 2016-11-16 20:08:17 | 1 | 52.00 |
| 20162 | 2016-11-16 20:09:18 | 1 | 52.00 |
| 20165 | 2016-11-16 20:10:21 | 1 | 52.00 |
| 20168 | 2016-11-16 20:11:27 | 1 | 52.00 |
+-------+---------------------+----+-------+
I'm very new to MYSQL so hopefully this is something easy to solve, but I haven't been able to find the solution (not for lack of trying).
The problem is the OR. You can use parentheses, or just use IN:
SELECT *
FROM data
WHERE ts BETWEEN '2016-11-27 00:11:00' AND '2016-11-29 00:11:00' AND
id IN (0, 1)
ORDER BY ts ASC
LIMIT 10;

MySQL - Query returning results in wrong order

The following MySQL queries below are returning results in different orders despite the "ORDER BY" being the same for both queries:
TABLE STRUCTURE
+-----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+---------+----------------+
| image_id | int(10) | NO | PRI | NULL | auto_increment |
| property_id | int(10) | NO | | 0 | |
| image_title | text | NO | | NULL | |
| image_title_id | int(10) | NO | | 0 | |
| image_index | smallint(3) | NO | | 0 | |
| image_version | tinyint(1) | NO | | 2 | |
| image_landscape | tinyint(1) | NO | | 1 | |
| image_visible | tinyint(1) | NO | | 1 | |
| image_type | tinyint(1) | NO | | 3 | |
+-----------------+-------------+------+-----+---------+----------------+
TEST 1
Query:
SELECT image_id, room_text
FROM property_record_images
INNER JOIN property_data_rooms ON property_record_images.image_title_id = property_data_rooms.room_id
WHERE property_id = 1029
ORDER BY image_index
Result:
+----------+-----------------+
| image_id | room_text |
+----------+-----------------+
| 2042 | Front elevation |
| 2043 | Garden to rear |
| 2044 | Kitchen |
| 2045 | Breakfast area |
| 2046 | Lounge |
| 2047 | Master bedroom |
| 2048 | Studio |
+----------+-----------------+
TEST 2
Query:
SELECT GROUP_CONCAT(CONCAT(property_record_images.image_id) SEPARATOR '|')
FROM property_record_images
INNER JOIN property ON property_record_images.property_id = property.property_id
WHERE property_record_images.property_id = 1029
ORDER BY image_index
Result:
+---------------------------------------------------------------------+
| GROUP_CONCAT(CONCAT(property_record_images.image_id) SEPARATOR '|') |
+---------------------------------------------------------------------+
| 2048|2047|2044|2045|2046|2043|2042 |
+---------------------------------------------------------------------+
This is occurring with random records (different "property_id") so it's not an simple as just reversing the ORDER BY for the second query.
Any idea why this is happening and where I have gone wrong with the query?
see http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_group-concat
I think you should get ordered group concat by:
SELECT GROUP_CONCAT(CONCAT(property_record_images.image_id) ORDER BY image_index SEPARATOR '|')
FROM property_record_images
INNER JOIN property ON property_record_images.property_id = property.property_id
WHERE property_record_images.property_id = 1029
ORDER BY image_index

insert values of query into table, even if no result in query (insert 0 values)

I am trying to solve a probably simple thing, being no expert at all # mysql
I have this first table 'online_players'
mysql> show columns from online_players;
+-------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+-------+
| Agent | varchar(255) | YES | | NULL | |
| Name | varchar(255) | YES | | NULL | |
| Alias | varchar(255) | YES | | NULL | |
| Begin_Date | varchar(100) | YES | | NULL | |
| LastBalanceUpdate | varchar(100) | YES | | NULL | |
| Session_minutes | varchar(100) | YES | | NULL | |
| Balance | varchar(100) | YES | | NULL | |
| Product | varchar(100) | YES | | NULL | |
+-------------------+--------------+------+-----+---------+-------+
8 rows in set (0.04 sec)
which is droped, recreated and value inserted every 3 minutes, it shows players on a website currently playing...
I then have this table 'players_count' :
mysql> show columns from players_count;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| date_count | varchar(50) | YES | | NULL | |
| players_count | varchar(10) | YES | | NULL | |
| product | varchar(10) | YES | | NULL | |
| avg_balance | varchar(100) | YES | | NULL | |
| id | int(11) | NO | PRI | NULL | auto_increment |
+---------------+--------------+------+-----+---------+----------------+
5 rows in set (0.07 sec)
When the table online_players is updated, the table players_count is updated with a specific insert:
USE livefeed;
INSERT INTO players_count(
date_count,players_count,product, avg_balance)
SELECT
now(),
count(Name) as Players,
Product,
Avg(Balance)
FROM
online_players
GROUP BY Product;
It works ok when at list 1 player is online:
mysql> select * from players_count
-> ;
+---------------------+---------------+---------+-------------+----+
| date_count | players_count | product | avg_balance | id |
+---------------------+---------------+---------+-------------+----+
| 2016-03-28 17:09:02 | 2 | USD | 0.06 | 1 |
| 2016-03-28 17:12:01 | 1 | USD | 0.12 | 2 |
| 2016-03-28 17:15:00 | 1 | USD | 0.12 | 3 |
| 2016-03-28 17:18:00 | 1 | USD | 0.12 | 4 |
| 2016-03-28 17:21:01 | 1 | USD | 0.12 | 5 |
| 2016-03-28 17:24:00 | 1 | USD | 0.12 | 6 |
+---------------------+---------------+---------+-------------+----+
6 rows in set (0.21 sec)
But I would also like to record a row in table players_count when NO player is online even if my query above = 0, for example:
+---------------------+---------------+---------+-------------+----+
| date_count | players_count | product | avg_balance | id |
+---------------------+---------------+---------+-------------+----+
| 2016-03-28 18:01:00 | 0 | USD | 0 | 7 |
| 2016-03-28 18:01:00 | 0 | FUN | 0 | 8 |
I use the table players_count to generate "real time" graphs and need to have 0 values for every specific date.
It might be simple but I have not found any solution online...
How shoud I modify my Insert/query to do this?
Thanks for your help