SQL Query, insert a max value from another table's column - mysql

I have two tables, a booking table and an invoice table. I am trying to update the booking table with booking information and get a max value from the invoice table and insert it into the booking table at the same time.
So far I have this, but it doesn't set any values to the Booking.Invoice_id column
INSERT INTO Booking( user_id, Location_id, Accom_Id,StartDate,EndDate,
Vehreg,PartySize,Invoice_id )
VALUES ('$User_id', '$pitch', '$Accom' , '$start',
'$end','$Vreg','$guests','SELECT Max Invoice_id FROM Invoice;');
any help would be much appreciated

Use insert . . . select:
INSERT INTO Booking(user_id, Location_id, Accom_Id, StartDate, EndDate,
Vehreg, PartySize, Invoice_id )
SELECT '$User_id', '$pitch', '$Accom' , '$start',
'$end', '$Vreg', ' $guests',
MAX(Invoice_ID)
FROM Invoice;
My guess, however, is that you want to run this immediately after inserting a row into Invoice. In that case, you should be using LAST_INSERT_ID().

Related

How do i sum up value from multiple rows from one table base on a condition and insert the sum up value to different table in mysql?

I am trying to select a value from a table(daily_interest_tbl) and sum up the value base on the customer ID and insert the sum up value and the customer ID to a different table (monthly_tbl).
The query will be call in an event to run end of every month.
try:
INSERT INTO monthly_tbl (NAMES_OF_THE_RESPECTIVE_COLUMNS_COMMA_SEPARATED)
(
SELECT daily_interest_tbl.customerID, SUM(daily_interest_tbl.NAME_OF_THE_VALUE_YOU_WANT_TO_SUM_UP)
FROM daily_interest_tbl
GROUP BY customerID
)

How to add a value to already existing value in column field and then insert the update value into another table

I Have a members table with a column amount which already has an integer value in it, I wish to add to that value and then use its contents to update another table called accounts which holds the amount being credited and the new balance (i.e After addition)
$this->query_array = array(':amt' => $amount, ':uid' => $userid, ':dat' => $date );
$this->query_string = "UPDATE members SET amount = amount + :amt;
INSERT INTO accounts VALUES ( :uid, :amt, members.amount + :amt, :dat);";
Thats my query above, am trying to get the members.amount table from the update query and use it in the insert query is there a better way, one that works than what I tried.
Sample Data :
Members Table userid amount
---------------------
u123 4000
y123 5000
Accounts Table userid credit balance date
Accounts table is currently empty so what I wanna do is add 300 to all values in memebrs table and then insert into accounts something like this.
Accounts Table userid credit balance date
-------------------------------------
u123 300 4300 11-11-11
y123 300 5300 11-11-11
I would use an insert ... select ... statement to achieve the desired outputs:
INSERT INTO accounts
SELECT members.userid, :amt, members.amount, :dat FROM members
Notes:
I'm using the members.amount in place of members.amount + :amt because the :amt has already been added once to members.amount.
Your update statement updates all records within the members table, yet the insert statement would create records for a specific user only. I believe you should restrict the update statement to the specific user only or not restrict the insert to a specific user. I chose the latter approach.
If you want to store the balance in a denormalised way, then I would rather use a trigger on the accounts table to update the balance in the members table, than to use 2 statements.
It's a simple insert by a select query, the only question is about the date
INSERT INTO Accounts (userid, credit, balance, date)
SELECT userid, 300, amount, NOW()
FROM Members;

2 Dates from the same column in one SQL query

I'm trying to work out an average between of time between two dates in the same field.
Basically i've got a transaction date and an id for each transaction and a customer id for each transaction.
I need to get the time between the first transaction and the second transaction. I dont mind working out the average between the two in excel but I dont know how to pull two dates from the same field.
transaction.created_at of the first transaction minus transaction.created_at of the second transaction for each and every customer in the database. I can pull the date of a transaction like
select
customer.id,
transaction.created_at
count(transaction.id)
from transaction
having count(transaction.id) = 2
Thanks
Not sure if this will always be Having count(*) = 2? If so, I think you could just use min and max, no?
/*
create table dbo.Example (tran_id int,created_at datetime,cust_id int)
insert dbo.example values (1,'10/1/2012',900)
insert dbo.example values (2,'10/2/2012',901)
insert dbo.example values (3,'10/18/2012',590)
insert dbo.example values (4,'10/10/2012',676)
insert dbo.example values (5,'10/11/2012',123)
insert dbo.example values (6,'10/17/2012',456)
insert dbo.example values (7,'10/9/2012',901)
insert dbo.example values (8,'10/30/2012',900)
insert dbo.example values (9,'10/4/2012',456)
insert dbo.example values (10,'10/17/2012',676)
*/
select
cust_id,
max([created_at]) as [Last Date],
min([created_at]) as [First Date],
datediff(hh,min([created_at]) ,max([created_at])) as [Hours diff]
from example
group by cust_id
having count(*) = 2
order by cust_id
Try the following to retrieve particular customer transactions count:
Select
Customer.id,
count(transaction.id)
from transaction
where Customer.id = '10'
Here 10 specifies the customer id that has been searched by you. You have to pass this customer id as parameter in your created SP.

SQL query to join two tables, adding new records if records missing

I have two tables, both with same data:
IP address | count
I need to combine the two tables into new one that contains data from both original tables.
IF there is a matching record in both tables, their count should be added.
IF there is a record that exists only in one table it gets copied over to the new table.
Let first table be called ip_data_january, second called ip_data_february and the one I am trying to create is ip_data_yearly. Thanks in advance.
1st insert only new ip addresses (with count starting at zero)
insert into ip_data_yearly (ip_adress, count)
(select distinct ip_address, '0' from jan_table
where ip_addess not in (select ip_adress from ip_data_yearly);
2nd update the count
update ip_data_yearly y
set count= count +
(select count(j.ip_adress) from jan_table where j.ip_adress=y.ip_adress);
..
3rd do this for all months
You can use ON DUPLICATE KEY UPDATE
I Assume Unique index on IP_Address .. then
INSERT INTO ip_data_yearly (ip_adress)
SELECT IP_Address FROM IP_Data_January
UNION ALL SELECT IP_Address FROM IP_Data_February
ON DUPLICATE KEY UPDATE `count`=`count`+1;
If the IP_Data_Yearly table is empty, an INSERT with a subquery that aggregates count by IP should do the trick:
INSERT INTO IP_Data_Yearly
SELECT IP_Address, SUM(Count)
FROM (
SELECT IP_Address, Count FROM IP_Data_January
UNION ALL SELECT IP_Address, Count FROM IP_Data_February
) IPCombined
GROUP BY IP_Address

SQL Insert into table only if record doesn't exist [duplicate]

This question already has answers here:
Check if a row exists, otherwise insert
(12 answers)
MySQL Conditional Insert
(13 answers)
Closed 9 years ago.
I want to run a set of queries to insert some data into an SQL table but only if the record satisfying certain criteria are met. The table has 4 fields: id (primary), fund_id, date and price
I have 3 fields in the query: fund_id, date and price.
So my query would go something like this:
INSERT INTO funds (fund_id, date, price)
VALUES (23, '2013-02-12', 22.43)
WHERE NOT EXISTS (
SELECT *
FROM funds
WHERE fund_id = 23
AND date = '2013-02-12'
);
So I only want to insert the data if a record matching the fund_id and date does not already exist. If the above is correct it strikes me as quite an inefficient way of achieving this as an additional select statement must be run each time.
Is there a better way of achieving the above?
Edit: For clarification neither fund_id nor date are unique fields; records sharing the same fund_id or date will exist but no record should have both the same fund_id and date as another.
This might be a simple solution to achieve this:
INSERT INTO funds (ID, date, price)
SELECT 23, DATE('2013-02-12'), 22.5
FROM dual
WHERE NOT EXISTS (SELECT 1
FROM funds
WHERE ID = 23
AND date = DATE('2013-02-12'));
p.s. alternatively (if ID a primary key):
INSERT INTO funds (ID, date, price)
VALUES (23, DATE('2013-02-12'), 22.5)
ON DUPLICATE KEY UPDATE ID = 23; -- or whatever you need
see this Fiddle.
Although the answer I originally marked as chosen is correct and achieves what I asked there is a better way of doing this (which others acknowledged but didn't go into). A composite unique index should be created on the table consisting of fund_id and date.
ALTER TABLE funds ADD UNIQUE KEY `fund_date` (`fund_id`, `date`);
Then when inserting a record add the condition when a conflict is encountered:
INSERT INTO funds (`fund_id`, `date`, `price`)
VALUES (23, DATE('2013-02-12'), 22.5)
ON DUPLICATE KEY UPDATE `price` = `price`; --this keeps the price what it was (no change to the table) or:
INSERT INTO funds (`fund_id`, `date`, `price`)
VALUES (23, DATE('2013-02-12'), 22.5)
ON DUPLICATE KEY UPDATE `price` = 22.5; --this updates the price to the new value
This will provide much better performance to a sub-query and the structure of the table is superior. It comes with the caveat that you can't have NULL values in your unique key columns as they are still treated as values by MySQL.
Assuming you cannot modify DDL (to create a unique constraint) or are limited to only being able to write DML then check for a null on filtered result of your values against the whole table
FIDDLE
insert into funds (ID, date, price)
select
T.*
from
(select 23 ID, '2013-02-12' date, 22.43 price) T
left join
funds on funds.ID = T.ID and funds.date = T.date
where
funds.ID is null