Mysql sum of every 5 data - mysql

Hello I have table named eod where i tons of data by date. here is the schema of the table:
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| ticker | varchar(20) | NO | MUL | NULL | |
| entry_date | date | NO | MUL | NULL | |
| high | float(10,2) | NO | MUL | NULL | |
| low | float(10,2) | NO | MUL | NULL | |
| close | float(10,2) | NO | MUL | NULL | |
| vol | int(11) | NO | MUL | NULL | |
+------------+-------------+------+-----+---------+----------------+
here are few sample of data:
+----+-----------+------------+------+------+-------+--------+
| ID | ticker | entry_date | high | low | close | vol |
+----+-----------+------------+------+------+-------+--------+
| 1 | x | 2013-02-20 | 6.70 | 6.50 | 6.50 | 136500 |
| 2 | y | 2013-02-24 | 6.60 | 6.40 | 6.40 | 174500 |
| 3 | z | 2013-02-25 | 6.60 | 6.40 | 6.40 | 214000 |
| 4 | x | 2013-02-26 | 6.50 | 6.30 | 6.40 | 238000 |
| 5 | x | 2013-02-27 | 6.50 | 6.20 | 6.20 | 279000 |
| 6 | a | 2013-02-28 | 6.20 | 6.00 | 6.00 | 260500 |
| 7 | x | 2013-03-03 | 6.10 | 5.70 | 5.70 | 131000 |
| 8 | a | 2013-03-04 | 6.10 | 5.80 | 6.00 | 150000 |
| 9 | x | 2013-03-05 | 6.20 | 6.00 | 6.00 | 95000 |
| 10 | z | 2013-03-06 | 6.10 | 6.00 | 6.00 | 84000 |
+----+-----------+------------+------+------+-------+--------+
I want to know how to get sum of every 5 vol, means from ID 1 to 5, then 6 to 10 .....continues by ticker.
sorry for creating confusion at the first time.

Try this:
SELECT sum(column), floor((id-1)/5) + 1 as min_id
FROM table_name
GROUP BY min_id

Try this
SELECT SUM(vol)
FROM (
SELECT vol, TRUNCATE(id/5,0) AS id
FROM eod) AS t
GROUP BY id
Not tested but logic is correct

Related

Complex INSERT or UPDATE MariaDB tables with data from other MariaDB tables using JOIN or UNION

I need to INSERT or UPDATE data in a table using data from other tables; I understand the basic
insert into table (a,b,c)
select h, i, j
from otherTable
where........
My challenge comes from the fact that the data is spread across multiple tables and in one of the tables the data is metadata stored in rows, not columns. Therefore I need to use JOIN and possible UNION to get what is needed.
Unfortunately after trying everything I read in both the Maria manual, on the Maria forum and on Stack overflow I can not get it to work.
Here is what I am attempting to do:
insert data into dbc_jot_groupmembers in the following fields using source data as shown:
jot_grpid = dbc_bp_groups_members.group_id
jot_bbmemid = dbc_bp_groups_members.user_id
jot_grpmemname = dbc_bp_xprofile_data.value where field_id=3
jot_grpmemnum = dbc_bp_xprofile_data.value where field_id=4
I need the final result to look like this:
select * from dbc_jot_groupmembers;
+--------------+-----------+----------------+---------------+---------------------+-------------+
| jot_grpmemid | jot_grpid | jot_grpmemname | jot_grpmemnum | jot_grpmemts | jot_bbmemid |
+--------------+-----------+----------------+---------------+---------------------+-------------+
| 1 | 17 | hutchdad | +17047047045 | 2021-06-15 14:56:19 | 14 |
| 2 | 24 | hutchdad | +17047047045 | 2021-06-15 19:49:58 | 14 |
| 3 | 25 | hutchdad | +17047047045 | 2021-06-15 19:49:58 | 14 |
| 4 | 17 | hutchmom | +17773274355 | 2021-06-15 19:49:58 | 15 |
| 5 | 24 | hutchmom | +17773274355 | 2021-06-15 19:49:58 | 15 |
| 6 | 16 | ledwards | +14567655645 | 2021-06-15 19:49:58 | 11 |
| 7 | 16 | medwards | +12223334545 | 2021-06-15 19:49:58 | 10 |
| 7 | 20 | medwards | +12223334545 | 2021-06-15 19:49:58 | 10 |
SAMPLE DATA FROM SOURCE TABELS AND TABLE DEFINITIONS:
MariaDB [devDisciplePlaceCom]> describe dbc_bp_groups_members;
+---------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| group_id | bigint(20) | NO | MUL | NULL | |
| user_id | bigint(20) | NO | MUL | NULL | |
| inviter_id | bigint(20) | NO | MUL | NULL | |
| is_admin | tinyint(1) | NO | MUL | 0 | |
| is_mod | tinyint(1) | NO | MUL | 0 | |
| user_title | varchar(100) | NO | | NULL | |
| date_modified | datetime | NO | | NULL | |
| comments | longtext | NO | | NULL | |
| is_confirmed | tinyint(1) | NO | MUL | 0 | |
| is_banned | tinyint(1) | NO | | 0 | |
| invite_sent | tinyint(1) | NO | | 0 | |
+---------------+--------------+------+-----+---------+----------------+
12 rows in set (0.002 sec)
describe dbc_bp_xprofile_data;
+--------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| field_id | bigint(20) unsigned | NO | MUL | NULL | |
| user_id | bigint(20) unsigned | NO | MUL | NULL | |
| value | longtext | NO | | NULL | |
| last_updated | datetime | NO | | NULL | |
+--------------+---------------------+------+-----+---------+----------------+
5 rows in set (0.001 sec)
THIS IS THE LIST OF GROUPS AND WHAT USERS THEY ARE IN.
select group_id,user_id from dbc_bp_groups_members ;
+----------+---------+
| group_id | user_id |
+----------+---------+
| 16 | 13 |
| 16 | 12 |
| 16 | 11 |
| 16 | 10 |
| 17 | 14 |
| 17 | 15 |
| 17 | 16 |
| 17 | 17 |
| 17 | 18 |
| 17 | 19 |
| 20 | 10 |
| 24 | 14 |
| 24 | 16 |
| 24 | 15 |
| 24 | 17 |
| 24 | 19 |
| 25 | 19 |
| 25 | 14 |
| 1 | 14 |
| 11 | 14 |
+----------+---------+
20 rows in set (0.000 sec)
THIS IS THE TABLE CONTAINING THE USERS METADATA. IN MY CASE I NEED THE PHOEN NUMBER AND NAME WHICH ARE IN THE value FIELD WITH A field_id of 3 and 4.
select * from dbc_bp_xprofile_data where user_id > 9 and field_id > 2 AND field_id < 5;
+-----+----------+---------+---------------+---------------------+
| id | field_id | user_id | value | last_updated |
+-----+----------+---------+---------------+---------------------+
| 31 | 3 | 10 | medwards | 2021-06-24 03:11:59 |
| 34 | 3 | 11 | ledwards | 2021-06-24 03:11:24 |
| 37 | 3 | 12 | nedwards | 2021-04-24 14:47:18 |
| 40 | 3 | 13 | iedwards | 2021-04-24 14:47:52 |
| 43 | 3 | 14 | hutchdad | 2021-06-21 14:53:08 |
| 46 | 3 | 15 | hutchmom | 2021-06-24 03:10:58 |
| 49 | 3 | 16 | hutchdaughter | 2021-04-24 16:54:48 |
| 52 | 3 | 17 | hutchson1 | 2021-04-24 16:55:43 |
| 55 | 3 | 18 | hutchson2 | 2021-04-24 16:57:42 |
| 58 | 3 | 19 | hutchson3 | 2021-04-24 16:58:44 |
| 78 | 3 | 25 | demoadmin | 2021-06-08 02:01:39 |
| 158 | 4 | 14 | 7047047045 | 2021-06-21 14:53:08 |
| 190 | 3 | 58 | dupdup | 2021-06-23 19:46:19 |
| 191 | 4 | 15 | 7773274355 | 2021-06-24 03:10:58 |
| 193 | 4 | 11 | 4567655645 | 2021-06-24 03:11:24 |
| 195 | 4 | 10 | 2223334545 | 2021-06-24 03:11:59 |
+-----+----------+---------+---------------+---------------------+
16 rows in set (0.000 sec)
If this can not be done is a single INSERT then I can use an INSERT with subsequent UPDATE statements. I also understand that this is not best practice and violates 3nf and probably several other best practice principles. Unfortunately, I am at the mercy of the application and can not change the code, so the only way to get this to work is to put duplicate data in the database as described below:
It can be done with a single INSERT. However, there are some information need to be addressed as what I've posted in a the comment. In the meantime, here is an example query that you can use to do the operation that you want:
SELECT ROW_NUMBER() OVER (ORDER BY A.group_id, A.user_id) AS 'jot_grpmemid',
A.group_id AS 'jot_grpid',
MAX(CASE WHEN B.field_id=3 THEN B.value ELSE '' END) AS 'jot_grpmemname',
MAX(CASE WHEN B.field_id=4 THEN CONCAT('+',B.value) ELSE '' END) AS 'jot_grpmemnum',
A.user_id AS 'jot_bbmemid'
FROM
dbc_bp_groups_members A JOIN dbc_bp_xprofile_data B
ON A.user_id=B.user_id
GROUP BY A.group_id, A.user_id;
Like I said in the comment, I'm not sure how you get/generate jot_grpmemid because you have two 7 in the expected result so I assume it's a typo. I guess, at this point it's up to you to modify the query accordingly.
Demo fiddle

mysql create multiple select to put max in all rows

This is my table with sample data:
Table:PersTrans
+------------+-------------+------+-----+------------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+------------+-------+
| PersTrID | char(10) | NO | PRI | | |
| PersTrSeq | int(11) | NO | PRI | 0 | |
| PersTrDate | date | YES | | 1001-01-01 | |
| PersTrPaid | float(9,2) | YES | | 0.00 | |
+------------+-------------+------+-----+------------+-------+
mysql> select * from PersTrans;
+------------+-----------+-----------+-------------+
| PersTrID | PersTrSeq | PersTrDate | PersTrPaid |
+------------+-----------+-----------+-------------+
| MOCK | 1 | 2015-10-10 | 400.00 |
| MOCK | 2 | 2017-11-07 | 10.00 |
| NAGA | 1 | 2015-11-11 | 500.00 |
| NASSA | 1 | 2015-12-16 | 800.00 |
+------------+-----------+-----------+-------------+
I'd like to pick up the maximum PersTrSeq, and attach it to all the records that have the same PersTrId. What I want:
+------------+-----------+------------+------------+----------------+
| PersTrID | PersTrSeq | PersTrDate | PersTrPaid | max(PersTrSeq) |
+------------+-----------+-----------+------------+-----------------+
| MOCK | 1 | 2015-10-10 | 400.00 | 2 |
| MOCK | 2 | 2017-11-07 | 10.00 | 2 |
| NAGA | 1 | 2015-11-11 | 500.00 | 1 |
| NASSA | 1 | 2015-12-16 | 800.00 | 1 |
+------------+-----------+-----------+------------+-----------------+
These two attempts didn't work. I've looked for other suggestions but haven't found anything helpful.
mysql> SELECT *, max(PersTrSeq) from PersTrans where PersTransId = 'Mock' group by PersTrSeq;
+------------+-----------+------------+------------+----------------+
| PersTrID | PersTrSeq | PersTrDate | PersTrPaid | max(PersTrSeq) |
+------------+-----------+-----------+------------+-----------------+
| MOCk | 1 | 2015-10-10 | 400.00 | 1 |
| MOCK | 2 | 2017-11-07 | 10.00 | 2 |
+------------+-----------+-----------+------------+-----------------+
mysql> SELECT *, max(PersTrSeq) as maxseq from PersTrans group by PersTrId;
+------------+-----------+------------+------------+--------+
| PersTrID | PersTrSeq | PersTrDate | PersTrPaid | maxseq |
+------------+------------+-----------+------------+--------+
| MOCK | 1 | 2015-10-10 | 400.00 | 2 |
| NAGA | 1 | 2015-11-11 | 500.00 | 1 |
| NASSA | 1 | 2015-12-16 | 800.00 | 1 |
+------------+-----------+-----------+------------+---------+
Can anyone offer a single query that will get the result I'm looking for?
Following query will work:
select *,
(select max(PersTrSeq) from PersTrans p2
where p2.PersTrId = p1.PersTrId
) as maxSeq
from PersTrans p1;
If I understand what you want, you want the same number of records as the actual data, substituting the max(PersTrSeq) for all rows with a certain PersTrID.
SELECT
`PerTrID`,
(SELECT max(`PersTrSeq`) FROM `PersTrans` b WHERE b.`PersTrID = a.`PersTrID`) as `PersTrSeq`,
`PersTrDate`,
`PersTrPaid`,
from `PersTrans` a

How To select Query

I have a table view named as tes.
+--------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+-------+
| id_oba | int(11) | NO | | NULL | |
| nama_obat | varchar(120) | NO | | NULL | |
| satuan | varchar(20) | YES | | NULL | |
| stok_awal | int(5) | YES | | NULL | |
| persediaan | int(5) | YES | | NULL | |
| nama_suplier | varchar(30) | NO | | NULL | |
| pemakaian | int(4) | NO | | NULL | |
| tanggal | date | YES | | NULL | |
+--------------+--------------+------+-----+---------+-------+
When I execute:
select id_oba, nama_obat, satuan, stok_awal, sum(pemakaian) AS pemakaian, persediaan,
from tes group by id_oba;
I get this result:
+--------+-----------+--------+-----------+-----------+------------+
| id_oba | nama_obat | satuan | stok_awal | pemakaian | persediaan |
+--------+-----------+--------+-----------+-----------+------------+
| 1 | Paramex | Botol | 30 | 40 | 5 |
| 2 | Oskadon | Botol | 30 | 41 | 27 |
| 3 | Lindon | Botol | 31 | 30 | 4 |
+--------+-----------+--------+-----------+-----------+------------+
How can I modify my query to get the result like this?
+--------+-----------+--------+-----------+-----------+------------+-------+
| id_oba | nama_obat | satuan | stok_awal | pemakaian | persediaan | total |
+--------+-----------+--------+-----------+-----------+------------+-------+
| 1 | Paramex | Botol | 30 | 40 | 5 | 45 |
| 2 | Oskadon | Botol | 30 | 41 | 27 | 67 |
| 3 | Lindon | Botol | 31 | 30 | 4 | 34 |
+--------+-----------+--------+-----------+-----------+------------+-------+
Please help me with my problem.
Thanks.
Change like this
select id_oba, nama_obat, satuan, stok_awal, sum(pemakaian) AS pemakaian,
persediaan,(sum(pemakaian)+persediaan) as total from tes group by id_oba;

rows missing with group by added

this is probably something very noob of me
i have the following table
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| from_id | int(11) | YES | MUL | NULL | |
| to_id | int(11) | YES | MUL | NULL | |
| reply_cost | int(5) | YES | | 0 | |
| date | timestamp | YES | | NULL | |
| body | text | YES | | NULL | |
| read_ | char(1) | YES | | 0 | |
| trash | tinyint(1) | YES | MUL | 0 | |
| trashDate | datetime | YES | | NULL | |
| ip_address | varchar(20) | YES | | NULL | |
+------------+-------------+------+-----+---------+----------------+
a select like
select id,from_id,to_id,date from mail where to_id='100' order by id desc limit 50;
returns
+----------+---------+-------+---------------------+
| id | from_id | to_id | date |
+----------+---------+-------+---------------------+
| 30071061 | 142 | 100 | 2013-08-15 04:39:56 |
| 30070785 | 282 | 100 | 2013-08-15 02:29:00 |
| 30064666 | 282 | 100 | 2013-08-14 16:10:39 |
| 30042809 | 458582 | 100 | 2013-08-12 15:50:45 |
| 30042560 | 458582 | 100 | 2013-08-12 15:28:39 |
| 30042557 | 458582 | 100 | 2013-08-12 15:28:22 |
| 30022845 | 458582 | 100 | 2013-08-10 17:32:40 |
| 30022834 | 458582 | 100 | 2013-08-10 17:31:22 |
| 30018276 | 458582 | 100 | 2013-08-10 06:09:27 |
| 30018275 | 458582 | 100 | 2013-08-10 06:09:00 |
but a select like this
select id,from_id,to_id,date from mail where to_id='100' group by from_id order by id desc limit 50;
outputs like this (from_id 282 is missing)
+----------+---------+-------+---------------------+
| id | from_id | to_id | date |
+----------+---------+-------+---------------------+
| 30017678 | 142 | 100 | 2013-08-10 01:56:38 |
| 29928935 | 189638 | 100 | 2013-07-31 18:33:01 |
| 29894382 | 458582 | 100 | 2013-07-27 22:15:53 |
| 29883054 | 409699 | 100 | 2013-07-26 15:22:35 |
any idea how this can be avoided ?
EDIT: forgot to mention, the goal is to return only one row per from_id.
What about the query
select id,from_id,to_id,date from mail where to_id='100' order by id, from_id desc limit 50;
That should work, hopefully.

How can I sub group my mysql results

I have following table in mysql
+-----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_profile_id | int(11) | NO | MUL | NULL | |
| latitude | float(10,6) | YES | | NULL | |
| longitude | float(10,6) | NO | | NULL | |
| modified | datetime | YES | | NULL | |
| created | datetime | YES | | NULL | |
+-----------------+-------------+------+-----+---------+----------------+
I want to do a query where I pass a list of user_profile_id s and I get their latest record back. Each user_profile_id has multiple records
sql : select id,user_profile_id,latitude,longitude,modified,created from user_locations where user_profile_id in(1044,1259);
+----+-----------------+-----------+-------------+---------------------+-------------------- -+
| id | user_profile_id | latitude | longitude | modified | created |
+----+-----------------+-----------+-------------+---------------------+---------------------+
| 14 | 1044 | 49.276867 | -123.120689 | 2011-12-24 00:50:22 | 2011-09-06 19:09:18 |
| 59 | 1044 | 49.276867 | -123.120689 | 2011-08-05 12:12:12 | 2011-11-01 00:00:00 |
| 60 | 1044 | 49.276867 | -123.120689 | 2010-08-05 12:12:12 | 2010-11-01 00:00:00 |
| 61 | 1044 | 49.276867 | -123.120689 | 2009-08-05 12:12:12 | 2009-11-01 00:00:00 |
| 62 | 1044 | 49.276867 | -123.120689 | 2008-08-05 12:12:12 | 2008-11-01 00:00:00 |
| 41 | 1259 | 49.276722 | -123.120735 | 2011-12-08 19:53:39 | 2011-12-07 19:38:02 |
+----+-----------------+-----------+-------------+---------------------+---------------------+
Example:
select *,max(created) from user_locations where user_profile_id IN (1044,1259) group by user_profile_id;
This query is wrong, how can fix this?
Thank you
select u.id,u.user_profile_id,u.latitude,u.longitude,u.modified,u.created
from user_locations u where u.user_profile_id in(1044,1259) and u.created =
(select max(g.created) from user_locations g where u.user_profile_id=g.user_profile_id) group by u.user_profile_id;