correctly updating mysql column - mysql

i have this query and i am updating mysql column but when there are more than two rows for same shop_id it updates the same data for all rows and i can understand why.
tableA
ida shop_id balance
1 25 5000
2 30 8015
3 32 7550
ida is unique but shop_id and balance is not unique
tableB
id fquota used
25 5000 50
30 8015 80
32 7550 75
tableB id and tableA shop_id are same
as i am getting the balance value in first
SELECT tableA.shop_id,tableA.ida,tableB.fquota,tableB.used from tableA INNER JOIN tableB ON tableA.shop_id=tableB.id where tableA.delivered='1' order by tableA.ida asc limit 20
if this query returns this sort of data then same balance is updated
shop_id ida fquota used
50 151 5000 50
50 152 5000 50
50 153 5000 50
60 154 6000 100
so u can see that shop_id 50 is coming 3 times and everytime the fquota and used is same as we are doing in one query 20 rows so defenitely it will give wrong result for balance and update same value in this case
// $balanceeeddfkdkd = $fquota - $used - 20;
// $balanceeeddfkdkd = 5000-50-20
// same 4930 will be updated in ida 151,152,153
while($row2 = mysqli_fetch_assoc($re991))
{
$idaaaa=$row2['ida'];
$fquota =$row2['fquota'];
$used =$row2['used'];
$balanceeeddfkdkd = $fquota - $used - 20;
mysqli_query($con,"update tableA set balance='$balanceeeddfkdkd' where ida='$idaaaa' ");
}
everything works as expected problem happens when there are multiple rows for same customer.
in that case same balance is updated for multiple rows, any help will be great.
i want exact balance for each rows and as customer consumes balance will decrease but in our case if 5 rows are coming in that query for one customer, all 5 rows will be updated with same balance and reason is obvious as fquota and used values are taken once when we query to mysql
we tried with this DISTINCT but dont know why it did not work. it should have worked/
SELECT DISTINCT tableA.shop_id,tableA.ida,tableB.fquota,tableB.used from tableA INNER JOIN tableB ON tableA.shop_id=tableB.id where tableA.delivered='1' order by tableA.ida asc limit 20

Your problem does not reproduce.
I am trying to reproduce it here:
SQL FIDDLE
Insert data that will reproduce your issue.

Related

Delete duplicate rows with lowest values in another column in mysql

I'm newbie, and I'm trying to delete duplicate rows with highest value in another column,
This is My database and result of below query
SELECT file_id,src,dst,durations,date_time, COUNT(*), MAX(durations) as
Max_durations
FROM C2
WHERE durations in (
SELECT max(durations)
FROM C2
GROUP BY src, dst
HAVING COUNT(*) >1)
GROUP BY src,dst
HAVING COUNT(*)>1
Now I want to remove Duplicate rows but keep rows that have maximum duration or equal Max_duration column and if have same duration delete one of them.
How can i do it...?
src
dst
duration
COUNT
Max_duration
12014504264
9726341011
464
20
684
12014504264
9726645434
320
8
875
12014556435
9726876431
765
4
900
12014576565
9726347656
43
7
600
12014508754
9726344537
233
2
233
12014764532
9726877654
655
2
54
12014587875
9726645443
1345
5
982
12014654536
9726766433
73
2
84
Assuming you are trying to actually delete rows from the table, not just have a query that omits certain rows:
To do this, just self-join with a row that would be preferred to the current one, so only rows where that is found are deleted:
delete C2
from C2
join C2 preferred on
preferred.src=C2.src and
preferred.dst=C2.dst and
preferred.durations >= C2.durations and
(preferred.durations > C2.durations or preferred.file_id < C2.file_id)
But to do this, you need some unique column to establish a precedence between multiple rows with the maximum duration; here I am using file_id and keeping the row with the lowest file_id.

MYSQL:Selecting SUM of a column but the column is based of another row ID

I want to have the sum of the beginning inventory of the entire year. The beginning inventory is based of the end_inventory of another month. The beginning_inventory_id contains the ID of another row which points to the end_inventory. How do I properly get the sum of the beginning_inventory of a certain year when it's based of another row's end_inventory. I have the following table
id
time_period
beginning_inventory_id
end_inventory
gross_sales
1
2020-09-01
null
1000
500
2
2020-10-01
1
2000
500
3
2020-11-01
2
3000
500
4
2020-12-01
3
4000
500
5
2021-01-01
4
5000
500
I have the following SQL query
SELECT SUM(a.gross_sales) as gross_sales, SUM(a.end_inventory) as end_inventory,
(SELECT SUM(b.end_inventory) FROM fs_summary as b WHERE a.beginning_inventory_id = b.id) as beginning_inventory
FROM fs_summary as a
WHERE YEAR(a.time_period) = 2020
Output I would like to generate is:
beginning_inventory = 6000
end_inventory = 10000
gross_sales = 2000
Instead, I am getting null on the beginning_inventory.
Any help would be great!
I am Assuming that you want to retrieve data from 1 table with self join.
SELECT SUM(a.gross_sales),SUM(a.end_inventory),SUM(b.end_inventory)
FROM fs_summary a, fs_aummary b
WHERE b.id=a.beginning_inventory_id AND YEAR(a.time_period) = 2020
using self join can help you in this situation
EDIT: You can also write this script as,
SELECT SUM(a.gross_sales),SUM(a.end_inventory),SUM(b.end_inventory)
FROM fs_summary a
INNER JOIN fs_aummary b
ON b.id=a.beginning_inventory_id
WHERE YEAR(a.time_period) = 2020
Using self-join SQL you can achieve your result instead of sub-queries.
You should specify the same table with two different names. Your query looks as below
select sum(virtual_tb.end_inventory) as 'beginning_inventory', sum(org_tb.end_inventory) as 'end_inventory', sum(org_tb.gross_sales) as 'gross_sales'
from fs_summary org_tb left join fs_aummary virtual_tb on (virtual_tb.beginning_inventory_id = org_tb.id)
where year(org_tb.time_period) = 2020;
(Approx Output)
beginning_inventory
end_inventory
gross_sales
6000
10000
2000

MySQL Select statement with several joins returns duplicated records

I have 4 tables with the following structure:
Table Groups
Groupid
groupname
groupadmin
Table GroupMembership
devid
groupid
Table GroupLocator
devid
name
pass
color
sampling
connected
forget
trace
Table GroupTracker
devid
groupid
latitude
longitude
timestamp
There is only one groupid='1' with groupname="FBorges"
Table GroupLocator has 2 records where devid points to grouid='1' on GroupMembership
GroupTracker has two records where groupid='1'
When I run the following SELECT:
SELECT GroupLocator.name, GroupLocator.color, GroupLocator.sampling,
GroupLocator.forget, GroupLocator.connected, GroupLocator.trace,
Groups.groupname, GroupTracker.latitude, GroupTracker.longitude,
GroupTracker.timestamp
FROM GroupMembership
JOIN GroupLocator ON GroupLocator.devid=GroupMembership.devid
JOIN Groups ON Groups.groupid=GroupMembership.groupid
JOIN GroupTracker ON GroupTracker.groupid=GroupMembership.groupid
WHERE GroupMembership.groupid=1;
I get the result:
name color sampling forget connected trace groupname latitude longitude timestamp
PCBorges 2 1 45 0 1 FBorges -22.883639 -42.822542 2020-01-08 20:29:24
Test 3 2 45 1 0 FBorges -22.883639 -42.822542 2020-01-08 20:29:24
PCBorges 2 1 45 0 1 FBorges -22.873639 -42.322542 2020-01-11 16:56:30
Test 3 2 45 1 0 FBorges -22.873639 -42.322542 2020-01-11 16:56:30
What I hope to get is:
name color sampling forget connected trace groupname latitude longitude timestamp
PCBorges 2 1 45 0 1 FBorges -22.883639 -42.822542 2020-01-08 20:29:24
Test 3 2 45 1 0 FBorges -22.883639 -42.822542 2020-01-08 20:29:24
EDIT: Removed my previous speculation after structure and data was provided and wrote a new answer:
I believe that you want to JOIN GroupTracker on devid instead of on groupid. Groupid 1 matches both rows in the GroupTracker table, so it will provide two results for each 1 row in GroupMemebership. Devid only matches one row. A correct JOIN is more efficient than your current GROUP BY solution (in comments) and may also produce more consistent results as your database grows.
SELECT gl.name, gl.color, gl.sampling,
gl.forget, gl.connected, gl.trace,
g.groupname, gt.latitude, gt.longitude,
gt.timestamp
FROM GroupMembership AS gm
JOIN GroupLocator AS gl ON gm.devid = gl.devid
JOIN Groups AS g ON gm.groupid = g.groupid
JOIN GroupTracker AS gt ON gm.devid = gt.devid
WHERE gm.groupid=1
;
I aliased all your tables so the query is much shorter and hence faster to write. I also swapped positions of all your JOIN clauses. I prefer to have the left table on the left side and the right table on the right side. Makes it easier to read. These two changes are not important. It's only style. The query will work perfectly without them.

How to get the lowest price from a particular group of users MYSQL

I have been at this for a few days without much luck and I am looking for some guidance on how to get the lowest estimate from a particular group of sullpiers and then place it into another table.
I have 4 supplier estimate on every piece of work and all new estimates go into a single table, i am trying to find the lowest 'mid' price from the 4 newsest entries in the 'RECENT QUOTE TABLE' with a group id of '1' and then place that into the 'LOWEST QUOTE TABLE' as seen below.
RECENT QUOTE TABLE:
suppid group min mid high
1 1 200 400 600
2 1 300 500 700
3 1 100 300 500
[4] [1] 50 [150] 300
5 2 1000 3000 5000
6 2 3000 5000 8000
7 2 2000 4000 6000
8 2 1250 3125 5578
LOWEST QUOTE TABLE:
suppid group min mid high
4 1 50 150 300
Any help on how to structure this would be great as i have been loking for a few days and have not been able to find anything to get me moving again, im using MYSQL and the app is made in Python im open to all suggestions.
Thanks in advance.
If you really want to select only row with group 1, you can do something like
INSERT INTO lowest_quote_table
SELECT * FROM recent_quote_table
WHERE `group` = 1
ORDER BY `mid` ASC
LIMIT 1.
If you want a row with the lowest mid from every group, you can do something like
INSERT INTO lowest_quote_table
SELECT rq.* FROM recent_quote_table AS rq
JOIN (
SELECT `group`, MIN(`mid`) AS min_mid FROM recent_quote_table
GROUP BY `group`
) MQ ON rq.`group` = MQ.`group` AND rq.`mid` = MQ.min_mid

Oracle query issue in implementing logic for checking on million records

I have a table A
code_Value key_value Description
12 12 Entry_Category5
13 rrtt Entry2
20 tht Entry6
20 trt Wntry9
Table A has similar ways million records..
A logic is implemented in Table B which uses Table A as source
Code_value Key_value Description
12 12 Entry_Category5
13 rrtt Entry2
13 13 Null value
20 tht Entry6
20 trt Entry9
20 20 Null value
The logic is, in table A if i have an entry, where code is not equal to key then a new entry of my previous code will be copied with key as the code,description must be null.
This logic must be applied to million records.I just want to have an sql query which will
help me.Please suggest since there are more records
Try:
insert into table_b
select
code_value,key_value,description
from
table_a
where
code_value = key_value
union
select
code_value,code_value,null
from
table_a
where
code_value != key_value