MySQL Update with Select Join - mysql

I have following tables as the simplest form.
Table "pro_details_old"
+------+------------+--------+------------+
| id | project_no | amount | pro_date |
+------+------------+--------+------------+
| 1000 | 001/001 | 50000 | 2018-10-01 |
| 1001 | 001/002 | 25000 | 2018-10-06 |
| 1002 | 002/004 | 75000 | 2018-10-12 |
| 1003 | 002/005 | 65000 | 2018-09-22 |
| 1004 | 002/006 | 10000 | 2018-08-17 |
| 1005 | 003/002 | 12000 | 2018-10-08 |
| 1006 | 003/003 | 145000 | 2018-07-01 |
+------+------------+--------+------------+
Table "pro_details_new"
+------+------------+--------+----------+
| id | project_no | amount | pro_date |
+------+------------+--------+----------+
| 1050 | 001/001 | 50000 | |
| 1051 | 001/002 | 25000 | |
| 1052 | 002/004 | 75000 | |
| 1053 | 002/005 | 65000 | |
| 1054 | 002/006 | 10000 | |
| 1055 | 003/002 | 12000 | |
| 1056 | 003/003 | 145000 | |
+------+------------+--------+----------+
02) So, I need to update issued_date column in "issues" table while comparing project_no of above 02 tables. ref_no & amount columns of "issues" table are already inserted. Expected output as follows.
+----+--------+--------+-------------+
| id | ref_no | amount | issued_date |
+----+--------+--------+-------------+
| 1 | 1050 | 50000 | 2018-10-01 |
| 2 | 1051 | 25000 | 2018-10-06 |
| 3 | 1052 | 75000 | 2018-10-12 |
| 4 | 1053 | 65000 | 2018-09-22 |
| 5 | 1054 | 10000 | 2018-08-17 |
| 6 | 1055 | 12000 | 2018-10-08 |
| 7 | 1056 | 145000 | 2018-07-01 |
+----+--------+--------+-------------+
03) I used the following query.
insert into issues
set issued_date =
(select pro_date
from pro_details_old
where
pro_details_old.project_no = pro_details_new.project_no)
left join pro_details_new on pro_details_new.id = issues.ref_no
04) I can not understand what is the wrong point. Can anyone help me ?

Update Query using join
Select the particular data which you want to update in issuestable using condition
update
issuestable as t3
join (
select
t1.id,
t1.pro_date
from
pro_details_old as t1
inner join pro_details_new as t2 on t1.project_no = t2.project_no
) t4 on t4.id = t3.ref_no
set
t3.issued_date = t4.pro_date
Insert Query
If you want to populate fresh data form pro_details_old & pro_details_new then you can use below insert query
INSERT INTO issues (ref_no, amount, issued_date)
VALUES
(
select
t1.id as ref_no,
t1.amount,
t1.pro_date as issued_date
from
pro_details_old as t1
inner join pro_details_new as t2 on t1.project_no = t2.project_no
)

Related

MySQL select statement missing some fields

I have following statement that is used to select some fields from MySQL DB
select finance_budget_issue.budget_date, SUM(finance_budget_issue.amount) AS amount, finance_vote.office_id as vote_office_id, finance_office.office_head as head,
finance_office.office_name AS office_name,
finance_budget.ref_no, finance_budget_issue.view_status, tbl_signature.office_head as sign_office_head, tbl_signature.name AS name,
tbl_signature.post AS post, tbl_signature.sign_id
from finance_budget_issue
inner join finance_budget on finance_budget.budget_id=finance_budget_issue.budget_id
left join finance_vote on finance_budget_issue.vote_id=finance_vote.vote_id
left join finance_vote_description on finance_vote.description=finance_vote_description.vote_description_id
left join finance_office on finance_budget_issue.office=finance_office.office_id
left join tbl_signature on finance_office.office_id=tbl_signature.office_id
The statement is working fine, but didn't outs the following fields
tbl_signature.office_head as sign_office_head,
tbl_signature.name AS name,
tbl_signature.post AS post
What may be going wrong ? I think that I used incorrect Joins. Can anyone help ?
Tables as follows :
finance_office
+----+-----------+-------------+------+
| id | office_id | office_name | head |
+----+-----------+-------------+------+
| 1 | 48 | A | SS |
| 2 | 69 | B | VV |
+----+-----------+-------------+------+
finance_vote
+---------+-----------+----------------+
| vote_id | office_id | vote |
+---------+-----------+----------------+
| 1 | 48 | 320-1-2-1-1001 |
| 2 | 48 | 320-2-2-2-2002 |
| 3 | 69 | 319-1-2-1-1001 |
| 4 | 69 | 319-1-2-2-1102 |
| 5 | 30 | 318-1-1-2-1101 |
+---------+-----------+----------------+
tbl_signature
+---------+-----------+---------+------------+-------------+
| sign_id | office_id | name | post | office_head |
+---------+-----------+---------+------------+-------------+
| 1 | 48 | Noel | Accountant | Manager |
| 2 | 69 | Jhon | Accountant | Manager |
| 3 | 30 | Micheal | Accountant | Manager |
+---------+-----------+---------+------------+-------------+
finance_budget
+-----------+--------+-------------+
| budget_id | ref_no | budget_date |
+-----------+--------+-------------+
| 1 | Acc/01 | 2020-01-20 |
| 2 | Acc/02 | 2020-01-22 |
+-----------+--------+-------------+
finance_budget_issue
+----+-----------+--------+---------------+-----------------+
| id | budget_id | amount | budget_status | transfer_status |
+----+-----------+--------+---------------+-----------------+
| 1 | 1 | 75000 | issues | Approved |
| 2 | 1 | 22000 | issues | Approved |
| 3 | 2 | 65000 | issues | Approved |
+----+-----------+--------+---------------+-----------------+
Desired Output
+--------+----------------+------+--------+------------------+------+------------+
| amount | vote_office_id | head | ref_no | sign_office_head | name | post |
+--------+----------------+------+--------+------------------+------+------------+
| 75000 | 48 | SS | Acc/01 | Manager | Noel | Accountant |
| 22000 | 48 | SS | Acc/01 | Manager | Noel | Accountant |
| 65000 | 69 | VV | Acc/02 | Manager | Jhon | Accountant |
+--------+----------------+------+--------+------------------+------+------------+
Generated Output (Incorrect)
+--------+----------------+------+--------+------------------+------+------+
| amount | vote_office_id | head | ref_no | sign_office_head | name | post |
+--------+----------------+------+--------+------------------+------+------+
| 75000 | 48 | SS | Acc/01 | | | |
| 22000 | 48 | SS | Acc/01 | | | |
| 65000 | 69 | VV | Acc/02 | | | |
+--------+----------------+------+--------+------------------+------+------+
This is easier to read:
SELECT i.budget_date
, SUM(i.amount) amount
, v.office_id vote_office_id
, o.office_head head
, o.office_name
, b.ref_no
, i.view_status
, s.office_head sign_office_head
, s.name
, s.post
, s.sign_id
FROM finance_budget_issue i
JOIN finance_budget b
ON b.budget_id = i.budget_id
LEFT
JOIN finance_vote v
ON v.vote_id = i.vote_id
LEFT
JOIN finance_vote_description d
ON d.vote_description_id = v.description
LEFT
JOIN finance_office o
ON i.office = o.office_id
LEFT
JOIN tbl_signature s
ON s.office_id = o.office_id
You have an aggregate function (and non-aggregated columns) but no GROUP BY clause; that's not going to work. You have a LEFT JOINed table from which you select no columns; that's pointless.
For further help, see Why should I provide an MCRE for what seems to me to be a very simple SQL query

Get only the records with most recent date to every code

I have a table like this
+------+-------+-----------+-------------+
| code | price | perct_off | date_review |
+------+-------+-----------+-------------+
| 0001 | 1500 | 40 | 2017-12-30 |
| 0001 | 1500 | 40 | 2018-02-15 |
| 0001 | 2000 | 25 | 2018-07-31 |
| 0002 | 3000 | 45 | 2018-03-20 |
| 0002 | 5000 | 20 | 2018-08-01 |
| 0003 | 3000 | 40 | 2018-01-16 |
+------+-------+-----------+-------------+
and I want to have only the records with the max date for every code. The iutput must be:
+------+-------+-----------+-------------+
| code | price | perct_off | date_review |
+------+-------+-----------+-------------+
| 0001 | 2000 | 25 | 2018-07-31 |
| 0002 | 5000 | 20 | 2018-08-01 |
| 0003 | 3000 | 40 | 2018-01-16 |
+------+-------+-----------+-------------+
When I try:
SELECT DISTINCT
(code), price, perct_off, MAX(date_review)
FROM `table01`
GROUP BY code
I've got this output
+-------+--------+------------+-------------------+
| code | price | perct_off | max(date_review) |
+-------+--------+------------+-------------------+
| 0001 | 1500 | 40 | 2018-07-31 |
| 0002 | 3000 | 45 | 2018-08-01 |
| 0003 | 3000 | 40 | 2018-01-16 |
+-------+--------+------------+-------------------+
How can I get the rigth output?
Thanks in advance.
One canonical way to do this is to join to subquery which finds the most recent date for each code:
SELECT t1.*
FROM table01 t1
INNER JOIN
(
SELECT code, MAX(date_review) AS max_date_review
FROM table01
GROUP BY code
) t2
ON t1.code = t2.code AND t1.date_review = t2.max_date_review;
Optimized solution:
SELECT
t1.code,
t1.price,
t1.perct_off,
t1.date_review
FROM t t1
LEFT JOIN t t2 ON
t1.code = t2.code
AND t1.date_review < t2.date_review
WHERE t2.date_review IS NULL;

Inner join on more than 2 tables

I have 3 different tables balance,received,expenses with following data in it.
Table received:
mysql> select * from received;
+-----+---------+-----------------+---------------------+
| rid | site_id | received_amount | receive_date |
+-----+---------+-----------------+---------------------+
| 1 | 1 | 500 | 2015-08-19 18:16:51 |
| 2 | 1 | 600 | 2015-08-19 18:16:52 |
| 3 | 1 | 500 | 2015-08-20 18:16:52 |
| 4 | 1 | 500 | 2015-08-19 18:16:52 |
+-----+---------+-----------------+---------------------+
Table expenses:
mysql> select * from expenses;
+-----+---------+----------------+---------------------+
| eid | site_id | expense_amount | expense_date |
+-----+---------+----------------+---------------------+
| 1 | 1 | 500 | 2015-08-19 18:17:11 |
+-----+---------+----------------+---------------------+
Table balance:
mysql> select * from balance;
+----------------+---------+---------------+--------------+-----------------+-----------------+------+------+---------------------+
| transaction_id | site_id | account_title | particulars | opening_balance | closing_balance | rid | eid | transaction_date |
+----------------+---------+---------------+--------------+-----------------+-----------------+------+------+---------------------+
| 1 | 1 | test1 | test1 values | 0 | 500 | 1 | NULL | 2015-08-19 18:16:51 |
| 2 | 1 | test1 | test1 values | 500 | 1100 | 2 | NULL | 2015-08-19 18:16:52 |
| 3 | 1 | test1 | test1 values | 1100 | 1600 | 3 | NULL | 2015-08-20 18:16:52 |
| 4 | 1 | test1 | test1 values | 1100 | 1600 | 4 | NULL | 2015-08-19 18:16:52 |
| 5 | 1 | test1 | test1 values | 1600 | 1100 | NULL | 1 | 2015-08-19 18:17:11 |
+----------------+---------+---------------+--------------+-----------------+-----------------+------+------+---------------------+
I am trying to merge the amount of received and expenses into balance table using following query but somehow I am not able to get correct way to get it.
select
b.transaction_id,
b.site_id,
b.account_title,
b.particulars,
b.opening_balance,
r.received_amount,
e.expense_amount,
b.closing_balance,
b.transaction_date
from
balance b
inner join received r
on b.site_id = r.site_id
inner join expenses e
on b.site_id = e.site_id
group by
b.transaction_id;
I am trying to get this output
+----------------+---------+---------------+--------------+-----------------+-----------------+----------------+-----------------+---------------------+
| transaction_id | site_id | account_title | particulars | opening_balance | received_amount | expense_amount | closing_balance | transaction_date |
+----------------+---------+---------------+--------------+-----------------+-----------------+----------------+-----------------+---------------------+
| 1 | 1 | test1 | test1 values | 0 | 500 | NULL | 500 | 2015-08-19 18:16:51 |
| 2 | 1 | test1 | test1 values | 500 | 600 | NULL | 1100 | 2015-08-19 18:16:52 |
| 3 | 1 | test1 | test1 values | 1100 | 500 | NULL | 1600 | 2015-08-20 18:16:52 |
| 4 | 1 | test1 | test1 values | 1600 | NULL | 500 | 1100 | 2015-08-19 18:16:52 |
| 5 | 1 | test1 | test1 values | 1100 | 500 | NULL | 1600 | 2015-08-19 18:17:11 |
+----------------+---------+---------------+--------------+-----------------+-----------------+----------------+-----------------+---------------------+
You are somewhat close. Instead of INNER JOIN, You need to do a LEFT-JOIN to the receipts and expenses. Since your "Balance" table has ALL transactions, it will drive which entry it sees within your underlying support tables. Also, don't just join on the site ID, but just the "rID" and "eID" since they would be your primary keys on the table anyhow.
No need to group by transaction ID as that is the primary key in the balance table and would only have one entry by a given ID.
select
b.transaction_id,
b.site_id,
b.account_title,
b.particulars,
b.opening_balance,
r.received_amount,
e.expense_amount,
b.closing_balance,
b.transaction_date
from
balance b
LEFT join received r
on b.rid = r.rid
AND b.site_id = r.site_id
LEFT join expenses e
on b.eid = e.eid
AND b.site_id = e.site_id
order by
b.site_id,
b.transaction_date

MySQL information from another table

I have the following SQL:
Select roleid , deity_level FROM default_jd_deity_role LIMIT 10;
That gives the output:
+--------+-------------+
| roleid | deity_level |
+--------+-------------+
| 1024 | 1 |
| 1043 | 54 |
| 1056 | 1 |
| 1057 | 54 |
| 1072 | 54 |
| 1074 | 45 |
| 1075 | 36 |
| 1088 | 45 |
| 1089 | 45 |
| 1104 | 27 |
+--------+-------------+
Then I have this SQL:
Select roleid , name FROM default_jd_ingame_roles LIMIT 22, 10
That gives the following output:
+--------+---------+
| roleid | name |
+--------+---------+
| 1024 | Hulu |
| 1043 | Cookiez |
| 1056 | Sam |
| 1057 | Sugar |
| 1072 | Leah |
| 1073 | Smexy |
| 1074 | Bam! |
| 1075 | Lexi |
| 1088 | OneShot |
| 1089 | Demono |
+--------+---------+
What I am trying to do is make deity_level add on to the second SQL Query like this:
+--------+---------+-------------+
| roleid | name | deity_level |
+--------+---------+-------------+
| 1024 | Hulu | 1 |
| 1043 | Cookiez | 54 |
| 1056 | Sam | 1 |
| 1057 | Sugar | 54 |
| 1072 | Leah | 54 |
| 1073 | Smexy | 45 |
| 1074 | Bam! | 36 |
| 1075 | Lexi | 45 |
| 1088 | OneShot | 45 |
| 1089 | Demono | 27 |
+--------+---------+-------------+
Try this:
Select a.roleid , a.deity_level, b.name
FROM default_jd_deity_role AS a
JOIN default_jd_ingame_roles AS b ON a.roleid=b.roleid
LIMIT 10
You can achieve this with a JOIN, like this:
SELECT main.roleid, roles.name, main.deity_level
FROM default_jd_deity_role main
LEFT JOIN default_jd_ingame_roles roles ON main.roleid = roles.roleid
LIMIT 22, 10
I'll leave two nice tutorials to get you started on JOINS:
http://www.sitepoint.com/understanding-sql-joins-mysql-database/
http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html
You are looking for a JOIN query:
SELECT igr.roleid , igr.name, dr.diety_level
FROM default_jd_ingame_roles igr
JOIN default_jd_deity_role dr ON dr.roleid = igr.roleid

mySQL getting wrong columns that don't match up with other columns in same row

I am new to mySQL and I could use some help with the following query.
I have a table relating engine settings to an experiment number and engine rpms,
and also another table relating engine performance to experiment number and engine.
here is the query i am doing
SELECT performance.exp_no, performance.rpm, ignition_timing, horse_power
FROM engine_settings, performance
WHERE performance.rpm = engine_settings.rpm
ORDER BY rpm;
| exp_no | rpm | ignition_timing | horse_power |
| 2 | 1000 | 24.50 | 105.23 |
| 2 | 1000 | 24.00 | 105.23 |
| 1 | 1000 | 24.50 | 100.23 |
| 1 | 1000 | 24.00 | 100.23 |
| 1 | 2000 | 25.50 | 125.03 |
| 1 | 2000 | 25.00 | 125.03 |
| 2 | 2000 | 25.50 | 129.03 |
| 2 | 2000 | 25.00 | 129.03 |
| 1 | 3000 | 26.50 | 154.65 |
| 1 | 3000 | 26.00 | 154.65 |
| 2 | 3000 | 26.50 | 159.65 |
| 2 | 3000 | 26.00 | 159.65 |
| 1 | 4000 | 27.50 | 178.23 |
| 1 | 4000 | 27.00 | 178.23 |
| 2 | 4000 | 27.50 | 184.23 |
| 2 | 4000 | 27.00 | 184.23 |
| 2 | 5000 | 28.50 | 195.36 |
| 2 | 5000 | 28.00 | 195.36 |
| 1 | 5000 | 28.50 | 189.36 |
| 1 | 5000 | 28.00 | 189.36 |
20 rows in set (0.06 sec)
Now take the first two rows for example. Ignition_timing for experiment 2 is actually 24.00, and for experiment 1 it is 24.5. So why do i get both values for experiment 2?
Here are the results I would like to be getting . . .
| exp_no | rpm | ignition_timing | horse_power |
| 2 | 1000 | 24.00 | 105.23 |
| 1 | 1000 | 24.50 | 100.23 |
| 1 | 2000 | 25.50 | 125.03 |
| 2 | 2000 | 25.00 | 129.03 |
| 1 | 3000 | 26.50 | 154.65 |
| 2 | 3000 | 26.00 | 159.65 |
| 1 | 4000 | 27.50 | 178.23 |
| 2 | 4000 | 27.00 | 184.23 |
| 2 | 5000 | 28.00 | 195.36 |
| 1 | 5000 | 28.50 | 189.36 |
What is the correct query to get the above table? Thanks in advance!
Just a group by/ DISCTINCT needed
SELECT
performance.exp_no,
performance.rpm,
ignition_timing,
DISTINCT(horse_power)
FROM
engine_settings
inner join performance ON performance.rpm = engine_settings.rpm
ORDER BY rpm;
OR
SELECT
performance.exp_no,
performance.rpm,
ignition_timing,
horse_power
FROM
engine_settings
inner join performance ON performance.rpm = engine_settings.rpm
GROUP BY horse_power
ORDER BY rpm;
Your query is not joining on all required field. You are only joining on the rpm fields your query and it appears that the join is incomplete.
SELECT performance.exp_no, performance.rpm, ignition_timing, horse_power
FROM engine_settings, performance WHERE performance.rpm = engine_settings.rpm
ORDER BY rpm;
You should change your query to the following:
SELECT performance.exp_no, performance.rpm, ignition_timing, horse_power
FROM engine_settings INNER JOIN performance
ON engine_setting.rpm=performance.rpm
AND engine_Settings.exp_no = performance.exp_no
ORDER BY rpm;
As I dont have the table structures I might be wrong but I suspect that both rpm and exp_no is a primary key or foreign key somewhere.
Hope this helps. On a side note look at the join syntax in my example it is considered the new standard the way you are writting a join is a bit outdates but not wrong.