MySQL update all values in column based on max date and group - mysql

I'm trying to use group by clause to update the dt column based on column 'last'. I need find last date for group 'group by hid,tid,tdate,fid,did,depid,acc' and set 'dt' value for all record in this group.
For example:
| id | hid | tid | tdate | fid | did | p2 | depid | acc | dt | last |
|----------|-------|-----|------------|-----|-----|-------|-------|------|------|----------------------|
| 3742030 | 12332 | 1 | 2017-09-02 | 1 | 1 | 9560 | 1 | 5334 | 1 | 2016-11-03T09:00:20Z |
| 3799297 | 2386 | 1 | 2017-08-29 | 1 | 1 | 8480 | 1 | 5352 | 1 | 2016-11-03T11:12:55Z |
| 4848877 | 2386 | 1 | 2017-08-29 | 1 | 1 | 8720 | 1 | 5352 | 2369 | 2016-12-17T16:59:22Z |
| 10706343 | 12332 | 1 | 2017-09-02 | 1 | 1 | 9660 | 1 | 5334 | 2065 | 2017-03-01T12:32:27Z |
| 14546682 | 2386 | 1 | 2017-08-29 | 1 | 1 | 11720 | 1 | 5352 | 4431 | 2017-05-12T10:24:09Z |
| 15824920 | 12332 | 1 | 2017-09-02 | 1 | 1 | 10820 | 1 | 5334 | 1111 | 2017-07-15T05:19:04Z |
to
| id | hid | tid | tdate | fid | did | p2 | depid | acc | dt | last |
|----------|-------|-----|------------|-----|-----|-------|-------|------|------|----------------------|
| 3742030 | 12332 | 1 | 2017-09-02 | 1 | 1 | 9560 | 1 | 5334 | 1111 | 2016-11-03T09:00:20Z |
| 3799297 | 2386 | 1 | 2017-08-29 | 1 | 1 | 8480 | 1 | 5352 | 4431 | 2016-11-03T11:12:55Z |
| 4848877 | 2386 | 1 | 2017-08-29 | 1 | 1 | 8720 | 1 | 5352 | 4431 | 2016-12-17T16:59:22Z |
| 10706343 | 12332 | 1 | 2017-09-02 | 1 | 1 | 9660 | 1 | 5334 | 1111 | 2017-03-01T12:32:27Z |
| 14546682 | 2386 | 1 | 2017-08-29 | 1 | 1 | 11720 | 1 | 5352 | 4431 | 2017-05-12T10:24:09Z |
| 15824920 | 12332 | 1 | 2017-09-02 | 1 | 1 | 10820 | 1 | 5334 | 1111 | 2017-07-15T05:19:04Z |
Schema:
http://sqlfiddle.com/#!9/4fad1d/1
Is there some way to update all rows in the table based on group?
Thanks

Join the table with the subquery that will find the most recent row per group.
update of t
join (
select t1.*
from of t1
join (
select hid,tid,tdate,fid,did,depid,acc, max(last) as last
from of
group by hid,tid,tdate,fid,did,depid,acc
) t2 using (hid,tid,tdate,fid,did,depid,acc,last)
) t3 using (hid,tid,tdate,fid,did,depid,acc)
set t.dt = t3.dt;
http://sqlfiddle.com/#!9/93708/2
For the join in the subquery you can also use NATURAL JOIN
natural join (
select hid,tid,tdate,fid,did,depid,acc, max(last) as last
from of
group by hid,tid,tdate,fid,did,depid,acc
) t2
http://sqlfiddle.com/#!9/e7e5ee/1

Related

MySQL select users who was in range of dates

Hello :) I need to create sql which will calculate advances for user but only for that one who was in work. Tables looks like:
users:
| id | firstName | lastName |
| -- | --------- | -------- |
| 1 | John 1 | Test 1 |
| 2 | John 2 | Test 2 |
| 3 | John 3 | Test 3 |
| 4 | John 4 | Test 4 |
users_advances:
| id | user_id | amount | d_add | status_id |
| -- | ------- | ------ | ---------- | --------- |
| 1 | 1 | 100 | 2022-07-09 | 1 |
| 2 | 1 | 50 | 2022-07-10 | 2 |
| 3 | 2 | 100 | 2022-07-03 | 1 |
| 4 | 2 | 50 | 2022-07-05 | 2 |
| 5 | 2 | 100 | 2022-03-09 | 1 |
| 6 | 1 | 50 | 2022-07-02 | 2 |
users_arrivals
| id | user_id | start_date | end_date |
| -- | ------- | ---------- | ---------- |
| 1 | 1 | 2022-09-01 | 2022-09-30 |
| 2 | 2 | 2022-09-22 | 2022-09-25 |
| 3 | 3 | 2022-09-19 | 2022-09-25 |
I created SQL
SELECT u.id AS user_id, CONCAT(u.firstName, SPACE(1), u.lastName) AS fullName, IFNULL(SUM(uz.amount), 0) AS suma
FROM users u
LEFT JOIN users_advances uz ON uz.user_id = u.id AND (uz.d_add BETWEEN '2022-09-19' AND '2022-09-25') AND ((uz.status_id = 1) OR (uz.status_id = 2))
LEFT JOIN users_arrivals po ON po.user_id = u.id
WHERE po.start_date <= '2022-09-19' AND po.end_date >= '2022-09-24'
GROUP BY u.id
but it doesnt return me user 2 who had start_date at 2022-09-22.

How to select row according to row in range of table 1 date with mysql?

I want to select picture file from photo_db where sid is the same as allotment_db so I wrote:
//allotment_db
+---------+---------+-----------+---------+
| id | rm_id | date | stts |
+---------+---------+-----------+---------+
| 1 | 1 |2019-10-01 | 1 |
| 2 | 2 |2019-10-01 | 1 |
| 3 | 3 |2019-10-01 | 1 |
| 4 | 1 |2019-10-02 | 1 |
| 5 | 2 |2019-10-02 | 1 |
+---------+---------+-----------+---------+
I want to select one row from photo_db ...
//photo_db
+---------+-----------+----------+-----------+
| id | rm_id | file | var |
+---------+-----------+----------+-----------+
| 1 | 1 | rm1.jpg | 0 |
| 2 | 1 | rm2.jpg | 0 |
| 3 | 1 | rm3.jpg | 9 |
| 4 | 2 | rm4.jpg | 0 |
| 5 | 2 | rm5.jpg | 9 |
| 6 | 2 | rm6.jpg | 0 |
| 7 | 3 | rm7.jpg | 0 |
| 8 | 3 | rm8.jpg | 0 |
| 9 | 3 | rm9.jpg | 9 |
| 10 | 1 | rm10.jpg | 0 |
+---------+-----------+----------+-----------+
Then, I wrote:
select *
from allotment_db alm
left
join photo_db pic
on pic.id = alm.id
where alm.date between '2019-10-01' and '2019-10-02'
and alm.stts = 1
and pic.var = 9
group
by alm.rm_id
And expect the result would come like this
//allotment_db
+---------+---------+-----------+---------+---------+
| id | rm_id | date | stts | file |
+---------+---------+-----------+---------+---------+
| 1 | 1 |2019-10-01 | 1 | rm3.jpg |
+---------+---------+-----------+---------+---------+
| 2 | 2 |2019-10-01 | 1 | rm5.jpg |
+---------+---------+-----------+---------+---------+
| 3 | 3 |2019-10-01 | 1 | rm9.jpg |
+---------+---------+-----------+---------+---------+
| 4 | 1 |2019-10-02 | 1 | rm3.jpg |
+---------+---------+-----------+---------+---------+
| 5 | 2 |2019-10-02 | 1 | rm5.jpg |
+---------+---------+-----------+---------+---------+
But the actual result return nothing even an error. Please correct me.
That is not how you should be using GROUP BY standard wise, also GROUP BY is not meant to "unduplicate" like that..
I assume you get a error when running your query?
SELECT list is not in GROUP BY clause and contains nonaggregated
column 'alm.id' which is not functionally dependent on columns in
GROUP BY clause; this is incompatible with
sql_mode=only_full_group_by"
From what it looks like you seams to be wanting these query resultsets to be merged as one resultset.
Query #1
SELECT
allotment_db.id
, allotment_db.rm_id
, allotment_db.date
, allotment_db.stts /* or (SELECT 1) AS stts -> 1 AS stts instead */
FROM
allotment_db
WHERE
allotment_db.date BETWEEN '2019-10-01' and '2019-10-02'
AND
stts = '1'
;
| id | rm_id | date | stts |
| --- | ----- | ---------- | ---- |
| 1 | 1 | 2019-10-01 | 1 |
| 2 | 2 | 2019-10-01 | 1 |
| 3 | 3 | 2019-10-01 | 1 |
| 4 | 1 | 2019-10-02 | 1 |
| 5 | 2 | 2019-10-02 | 1 |
Query #2
SELECT
photo_db.rm_id
, photo_db.file
FROM
photo_db
WHERE
photo_db.var = '9'
;
| rm_id | file |
| ----- | ------- |
| 1 | rm3.jpg |
| 2 | rm5.jpg |
| 3 | rm9.jpg |
So a option would be ..
Query
SELECT
allotment_db.id
, allotment_db.rm_id
, allotment_db.date
, allotment_db.stts /* or (SELECT 1) AS stts -> 1 AS stts instead */
, photo_db.rm_id
, photo_db.file
FROM (
SELECT
allotment_db.id
, allotment_db.rm_id
, allotment_db.date
, allotment_db.stts /* or (SELECT 1) AS stts -> 1 AS stts instead */
FROM
allotment_db
WHERE
allotment_db.date BETWEEN '2019-10-01' and '2019-10-02'
AND
stts = '1'
) AS allotment_db
INNER JOIN (
SELECT
photo_db.rm_id
, photo_db.file
FROM
photo_db
WHERE
photo_db.var = '9'
) AS photo_db
ON
allotment_db.rm_id = photo_db.rm_id
ORDER BY
id ASC
, allotment_db.rm_id ASC
Result
| id | rm_id | date | stts | rm_id | file |
| --- | ----- | ---------- | ---- | ----- | ------- |
| 1 | 1 | 2019-10-01 | 1 | 1 | rm3.jpg |
| 2 | 2 | 2019-10-01 | 1 | 2 | rm5.jpg |
| 3 | 3 | 2019-10-01 | 1 | 3 | rm9.jpg |
| 4 | 1 | 2019-10-02 | 1 | 1 | rm3.jpg |
| 5 | 2 | 2019-10-02 | 1 | 2 | rm5.jpg |
see demo

Mysql inner join or left join

I have 1 table products and I would like to extract price of products with type A and B. I try to use INNER JOIN but it returns duplicate record. How can I do this?
id | Price | Date | Type | Size |
-------------------------------------------------------
1 | 1,00 | 01/11/2010 | A | 7,00 |
2 | 2,50 | 02/11/2010 | A | 8,00 |
3 | 2,50 | 03/11/2010 | A | 9,00 |
4 | 3,00 | 02/11/2010 | A | 10,00 |
5 | 4,00 | 03/11/2010 | A | 11,00 |
6 | 4,00 | 03/11/2010 | A | 12,00 |
7 | 5,00 | 03/11/2010 | A | 13,00 |
8 | 5,00 | 03/11/2010 | A | 14,00 |
9 | 6,00 | 03/11/2010 | A | 15,00 |
10 | 7,00 | 03/11/2010 | A | 16,00 |
11 | 1,00 | 03/11/2010 | B | 17,00 |
12 | 2,50 | 03/11/2010 | B | 18,00 |
13 | 3,00 | 03/11/2010 | B | 19,00 |
14 | 3,00 | 03/11/2010 | B | 20,00 |
15 | 5,00 | 03/11/2010 | B | 21,00 |
16 | 6,00 | 03/11/2010 | B | 22,00 |
17 | 7,00 | 03/11/2010 | B | 23,00 |
18 | 7,00 | 03/11/2010 | B | 24,00 |
And I would like to build a table like this:
Price | Date | Size A | Size B |
-------------------------------------------------------
1,00 | 01/11/2010 | 7,00 | 17,00 |
2,50 | 02/11/2010 | 8,00 | |
2,50 | 03/11/2010 | 9,00 | 18,00 |
3,00 | 02/11/2010 | 10,00 | 19,00 |
4,00 | 03/11/2010 | 11,00 | |
4,00 | 04/11/2010 | 12,00 | |
5,00 | 03/11/2010 | 13,00 | 21,00 |
5,00 | 04/11/2010 | 14,00 | |
6,00 | 05/11/2010 | 15,00 | |
7,00 | 06/11/2010 | 16,00 | 23,00 |
How can I do that in one query?
Thanks for any help.
select price,
date,
sum(case when `type` = 'A' then size else 0 end) as SizeA,
sum(case when `type` = 'B' then size else 0 end) as SizeB
from products
group by price, date
order by price, date
Group by the date to get the data for each date. To get the other columns you need to use aggregate functions like sum().
If you really need the null values you can do:
case when sum(`type` = 'A') = 0
then null
else sum(case when `type` = 'A' then size end)
end

Select Same Column From 2 Tables into 1 Column in View

I have two column with the same name in different tables.
I want to join them into one column in a view.
Here my first table stocks:
+----------+------------+------------+---------+----------------+--------+
| stock_id | stock_cost | stock_left | item_id | purchasedtl_id | trx_id |
+----------+------------+------------+---------+----------------+--------+
| 1 | 1000 | 0 | 1 | 1 | 1 |
| 2 | 1000 | 5 | 1 | 2 | 2 |
| 3 | 1000 | 1 | 1 | 3 | 4 |
+----------+------------+------------+---------+----------------+--------+
Second table stocks_out
+-------------+----------------+--------------+---------+----------+------------+--------+
| stockout_id | stockout_price | stockout_qty | item_id | stock_id | saledtl_id | trx_id |
+-------------+----------------+--------------+---------+----------+------------+--------+
| 1 | 2000 | 1 | 1 | 1 | 1 | 3 |
+-------------+----------------+--------------+---------+----------+------------+--------+
And I want to join them to be like this trx_id, trx_no, trx_closetime, trx_type stock_id, stock_cost, stockout_id, stock_out_cost, stockout_price, item_id
item_id is the field I want to join in one column.
The current Query is :
select `transactions`.`trx_id` AS `trx_id`,`transactions`.`trx_no` AS `trx_no`,`transactions`.`trx_closetime` AS `trx_closetime`,`transactions`.`trx_type` AS `trx_type`,`stocks`.`stock_id` AS `stock_id`,`stocks`.`stock_cost` AS `stock_cost`,`stock_out`.`stockout_id` AS `stockout_id`,`stock_out`.`stockout_price` AS `stockout_price` from ((`transactions` left join `stocks` on(`stocks`.`trx_id` = `transactions`.`trx_id`)) left join `stock_out` on(`stock_out`.`trx_id` = `transactions`.`trx_id`)) order by `transactions`.`trx_closetime`;
And the current result:
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+
| trx_id | trx_no | trx_closetime | trx_type | stock_id | stock_cost | stockout_id | stockout_price |
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+
| 1 | 02002-02-170415-001 | 2017-04-15 19:40:03 | 2 | 1 | 1000 | NULL | NULL |
| 2 | 02002-02-170415-002 | 2017-04-15 19:40:13 | 2 | 2 | 1000 | NULL | NULL |
| 3 | 02002-01-170415-001 | 2017-04-15 19:40:57 | 1 | NULL | NULL | 1 | 2000 |
| 4 | 02002-02-170415-003 | 2017-04-15 19:41:14 | 2 | 3 | 1000 | NULL | NULL |
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+
Found it guys.
I just need to add the following query as the column
COALESCE(`stocks`.`item_id`, `stocks_out`.`item_id`) AS `item_id`
So the query will be like
select `transactions`.`trx_id` AS `trx_id`,`transactions`.`trx_no` AS `trx_no`,`transactions`.`trx_closetime` AS `trx_closetime`,`transactions`.`trx_type` AS `trx_type`,`stocks`.`stock_id` AS `stock_id`,`stocks`.`stock_cost` AS `stock_cost`,`stock_out`.`stockout_id` AS `stockout_id`,`stock_out`.`stockout_price` AS `stockout_price`, COALESCE(`stocks`.`item_id`, `stocks_out`.`item_id`) AS `item_id from ((`transactions` left join `stocks` on(`stocks`.`trx_id` = `transactions`.`trx_id`)) left join `stock_out` on(`stock_out`.`trx_id` = `transactions`.`trx_id`)) order by `transactions`.`trx_closetime`;
And the result:
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+---------+
| trx_id | trx_no | trx_closetime | trx_type | stock_id | stock_cost | stockout_id | stockout_price | item_id |
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+---------+
| 1 | 02002-02-170415-001 | 2017-04-15 19:40:03 | 2 | 1 | 1000 | NULL | NULL | 1 |
| 2 | 02002-02-170415-002 | 2017-04-15 19:40:13 | 2 | 2 | 1000 | NULL | NULL | 1 |
| 3 | 02002-01-170415-001 | 2017-04-15 19:40:57 | 1 | NULL | NULL | 1 | 2000 | 1 |
| 4 | 02002-02-170415-003 | 2017-04-15 19:41:14 | 2 | 3 | 1000 | NULL | NULL | 1 |
+--------+---------------------+---------------------+----------+----------+------------+-------------+----------------+---------+

How to calculate the total value of two column from 3 different tables?

For example,I have 3 tables;
table1:
+-------+
| count |
+-------+
| 1 |
| 0 |
| 0 |
| 0 |
| 3 |
+-------+
table2:
+-------+
| count |
+-------+
| 3 |
| 0 |
| 0 |
| 0 |
| 0 |
+-------+
table3:
+-------+
| count |
+-------+
| 1 |
| 1 |
| 0 |
| 0 |
| 1 |
+-------+
I want to calculate table1.count+table2.count+table3.count, to get the result,table_right:
+-------+
| count |
+-------+
| 5 | (1+3+1=5)
| 1 | (0+0+1=1)
| 0 | (0+0+0=0)
| 0 | (0+0+0=0)
| 4 | (3+0+1=4)
+-------+
However, if I use command :
select table1.count+table2.count+table3.count as total
from table1,table2,table3;
The result will become to:
+-------+
| total |
+-------+
| 5 |
| 4 |
| 4 |
| 4 |
| 7 |
| 2 |
| 1 |
| 1 |
| 1 |
| 4 |
| 2 |
| 1 |
| 1 |
| 1 |
| 4 |
| 2 |
| 1 |
| 1 |
| 1 |
| 4 |
| 2 |
| 1 |
| 1 |
| 1 |
| 4 |
| 5 |
| 4 |
| 4 |
| 4 |
| 7 |
| 2 |
| 1 |
| 1 |
| 1 |
| 4 |
| 2 |
| 1 |
| 1 |
| 1 |
| 4 |
| 2 |
| 1 |
| 1 |
| 1 |
| 4 |
| 2 |
| 1 |
| 1 |
| 1 |
| 4 |
| 4 |
| 3 |
| 3 |
| 3 |
| 6 |
| 1 |
| 0 |
| 0 |
| 0 |
| 3 |
| 1 |
| 0 |
| 0 |
| 0 |
| 3 |
| 1 |
| 0 |
| 0 |
| 0 |
| 3 |
| 1 |
| 0 |
| 0 |
| 0 |
| 3 |
| 4 |
| 3 |
| 3 |
| 3 |
| 6 |
| 1 |
| 0 |
| 0 |
| 0 |
| 3 |
| 1 |
| 0 |
| 0 |
| 0 |
| 3 |
| 1 |
| 0 |
| 0 |
| 0 |
| 3 |
| 1 |
| 0 |
| 0 |
| 0 |
| 3 |
| 5 |
| 4 |
| 4 |
| 4 |
| 7 |
| 2 |
| 1 |
| 1 |
| 1 |
| 4 |
| 2 |
| 1 |
| 1 |
| 1 |
| 4 |
| 2 |
| 1 |
| 1 |
| 1 |
| 4 |
| 2 |
| 1 |
| 1 |
| 1 |
| 4 |
+-------+
This is not the result i want, If I try
select distinct table1.count+table2.count+table3.count as total
from table1,table2,table3;
I will get:
+-------+
| total |
+-------+
| 5 |
| 4 |
| 7 |
| 2 |
| 1 |
| 3 |
| 6 |
| 0 |
+-------+
Still isn't the result I want. How could i do to get table_right?
if you add a common id (lets call id rowId and lets assume it has the same name on every table),
SELECT t1.count + t2.count + t3.count AS total
FROM table1 AS t1
LEFT JOIN table2 AS t2 using (rowId)
LEFT JOIN table3 AS t3 using (rowId)
if you not have those ids, all i can think about its summing all t1 then all t2 then all t3 and finally add the results together.
SELECT t1+t2+t3 as total
FROM (SELECT (SELECT SUM(count) from table1) as t1,
(SELECT SUM(count) from table2) as t2,
(SELECT SUM(count) from table3) as t3
)
Check out this SQLFiddle
EDIT (2)
to add rowId just alter the tables:
ALTER TABLE table1 ADD COLUMN rowId int not null auto_increment primary key;
ALTER TABLE table2 ADD COLUMN rowId int not null auto_increment primary key;
ALTER TABLE table3 ADD COLUMN rowId int not null auto_increment primary key;