I'm trying to get all the items of the cart_items and add it to the ticket_items.
I've the error "SUBQUERY RETURN MULTIPLE ROWS", but that's what I want, insert all that rows in the ticket_items table in a same query.
INSERT INTO ticket_items (ticket_id, ISBN, quantity)
VALUES (
(SELECT COUNT(ticket_id) FROM ticket),
(SELECT ISBN FROM cart_items WHERE customer_id = 1),
(SELECT quantity FROM cart_items WHERE customer_id = 1)
);
The issue is that you are using an aggregate function (COUNT) that will build exactly one value, but both isbn and quantity occur twice or more. So, the insert that will be built by your query is something like
INSERT INTO ticket_items (ticket_id, ISBN, quantity)
VALUES (10, 1,2,3, 4,5,6);
This is of course not allowed. Since you do a COUNT, you need to apply GROUP BY to create multiple rows which will be inserted.
So your insert command will be something like this:
INSERT INTO ticket_items (ticket_id, ISBN, quantity)
((SELECT COUNT(ticket_id), ISBN, quantity
FROM ticket, cart_items
WHERE customer_id = 1
GROUP BY ISBN, quantity));
This will work correctly and do what you asked for, I created an example here: db<>fiddle
You should check if this is really what you want because for me, it doesn't make sense to insert the count of ticket_id like you describe. But this is something you must check on your own.
Don't use VALUES keyword.
Please see syntax below:
INSERT INTO table2 (column1, column2, column3, ...)
SELECT column1, column2, column3, ...
FROM table1
WHERE condition;
I would first make sure that select gives you the expected result, then issue the insert statement.
Upon review, I believe the issue is with SELECT part.
You should rewrite it as one SELECT:
INSERT INTO ticket_items (ticket_id, ISBN, quantity)
(SELECT
(SELECT COUNT(ticket_id) from ticket) as ticket_id, ISBN, quantity
FROM cart_items
WHERE customer_id = 1)
Good luck!
Related
I have a below table.
Now I need output like below.
Now I need to display the product differences between the consecutive dates based on product group by. For example: in an Apple loop, the first row should return the default value of 3 and then the next row should return the difference value. Similarly, the code should work on for the next product Samsung loop. Then, the result should be passed into a new column as displayed in the required output.
I am totally new to MySQL, however, I have tried my best to use a join to get the desired output, but I have no idea from where to start. Please guide me on this new concept.
Below are my code which I have tried.
CREATE TABLE products (
id numeric,
product text,
date_value DATE,
prod_value numeric);
INSERT INTO products(id, product, date_value, prod_value)
VALUES(1, 'Apple', '2018-01-22', 3);
INSERT INTO products(id, product, date_value, prod_value)
VALUES(2, 'Apple', '2018-01-23', 6);
INSERT INTO products(id, product, date_value, prod_value)
VALUES(3, 'Apple', '2018-01-24', 7);
INSERT INTO products(id, product, date_value, prod_value)
VALUES(4, 'Samsung', '2018-01-22', 1);
INSERT INTO products(id, product, date_value, prod_value)
VALUES(5, 'Samsung', '2018-01-23', 5);
SELECT
current.prod_value,(current.prod_value - previous.prod_value) diff
FROM
products previous
JOIN
products current
ON
current.id = previous.id+1;
You can use correlated sub-query (for older version), if you are runing with newer version of MySQL then you can use lag() :
select p.*,
p.prodvalue - (select coalesce(p2.prodvalue, 0)
from product p1
where p1.product = p.product and p1.id < p.id
order by p1.id desc
limit 1
) as proddiff
from product p;
Use lag():
select p.*,
(p.prod_value -
lag(p.prod_value, 1, 0) over (partition by product order by date_value)
) as prod_diff
from products p;
I want to insert many rows into two relative tables. I used LAST_INSERTED_ID() to insert data into the second table, but this id does not change
BEGIN;
insert into themes (tutorID, year, theme_name, degreeID)
select tutorID, year, work_name, degreeID from journal;
INSERT INTO assigned_students (studentID, tutorID, themeID, writing_language_id, work_typeID)
select studentID, tutorID, LAST_INSERT_ID(), 0, 4 from journal;
COMMIT
Give this a try, where you declare a INT and then set that value, see below.
BEGIN;
declare lastid INT;
insert into table1 (tutorID, year, name, degreeID)
select sm.tutorID, year, namework, dt.degreeID from table3;
set lastid = (SELECT LAST_INSERT_ID());
INSERT INTO table2 (studentID, tutorID, table1ID, writing_language_id, work_typeID)
select distinct StudentID, tutorID, lastid , 0, 4 from table3;
COMMIT;
You can also try this.
BEGIN;
insert into table1 (tutorID, year, name, degreeID)
select sm.tutorID, year, namework, dt.degreeID from table3;
INSERT INTO table2 (studentID, tutorID, table1ID, writing_language_id, work_typeID)
select distinct StudentID, tutorID, (SELECT LAST_INSERT_ID()), 0, 4 from table3;
COMMIT;
Make the inserts into assigned_students reference the just-inserted rows from themes (so you can get their auto generated IDs) also:
BEGIN;
insert into themes (tutorID, year, theme_name, degreeID)
select themeID, year, work_name, degreeID from journal;
INSERT INTO assigned_students (studentID, tutorID, themeID, writing_language_id, work_typeID)
select j.studentID, j.tutorID, t.THEME_ID_COLUMN_NAME, 0, 4
from
journal j
inner join themes t on j.themeID = t.tutorid;
COMMIT
Here we see that first we make some inserts into themes, and I presume it will autogenerate some IDs for themes' pk column.
So we then join journal onto those rows we inserted so we can retrieve the generated IDs
I don't know what the PK column of themes is called, so you'll have to replace THEME_ID_COLUMN_NAME with the correct value
Note that you might have to specify additional columns in on j.themeID = t.tutorid than just the tutorid, if that doesnt uniquely identify a row
I read also that for autoincrement columns it is guaranteed that the IDs are sequential, so you can get the LAST_INSERTED_ID() which is the mos trecently inserted row) as well as the ROW_COUNT and hence know the range of IDs that was inserted, and use that to select/join the journal data
I have created table A as follows:
I put in the data above using a simple INSERT INTO and SELECT statement. Now that the source data is corrected, I want to used the INSERT INTO, SELECT, ON DUPLICATE KEY UPDATE, but when I run the code, the 0's and NULL that you see above does not update to the new value.
Here is my code
INSERT INTO
TABLEA (uniqueid, year, month, costcentre, amount)
SELECT
SS.uniquekey, SS.year, SS.month, SS.source, SS.totalamount
FROM
(SELECT
uniquekey, `YEAR`, `MONTH`, SOURCE, totalamount
FROM
TABLEB
UNION ALL
SELECT
uniquekey, `YEAR`, `MONTH`, SOURCE, totalamount
FROM
TABLEC
) as SS
ON DUPLICATE KEY
UPDATE
TABLEA.YEAR = VALUES(SS.year),
TABLEA.MONTH = VALUES(SS.month),
TABLEA.COSTCENTRE = VALUES(SS.SOURCE),
TABLEA.AMOUNT = VALUES(SS.TOTALAMOUNT)
;
So the answer I am looking for, is:
I want TABLEA to have a line for each UNIQUE that is in the SELECT query.
If TABLEA contains the same UNIQUEID as the SELECT, then I want it to update the YEAR, MONTH, COSTCENTRE, AMOUNT from the SELECT query
Converted my comment to an answer.
I believe that it should be ON DUPLICATE KEY UPDATE YEAR = VALUES(YEAR) - i.e. you should refer to the column names of TABLEA only
I have 3 tables
works (id, name, date_started, date_finished, type_id, employer_id)
types (id, type)
employers (id, name, last_name, company)
I want when inserting into works table records in one query to insert into columns: name, date (by hand), then also into type_id and employer_id columns (selecting id from other tables)
I know you can insert and then use select, but how do i add the other values, that i need to type by hand as they dont exist on other tables?
You can just put the extra values directly in the SELECT clause:
INSERT INTO works (name, date_started, type_id, employer_id)
SELECT name, curdate(), type_id, employer_id
FROM types t
JOIN employers e ON ...
WHERE ...
You can have subqueries inside VALUES() clause, provided the subquery will only return one value.
INSERT INTO works (name, date_started, date_finished, type_id, employer_id)
VALUES
(
'name here',
'date started',
'date finished',
(SELECT id FROM types WHERE type = 'val' LIMIT 1),
(SELECT id FROM employers WHERE name = 'val' LIMIT 1)
)
I have two tables:
purchase_mis(id, user_id, total_purchased, date)
daily_purchase(id, user_id, product_id, paid_amount, purchase_date)
I have a CRON file that runs every night, it counts the daily purchase from the "daily_purchase" table and runs insert into "purchase_mis".
For example:
SELECT
COUNT(*) AS purchase_count,
purchase_date
FROM daily_purchase
GROUP BY user_id;
This returns the purchase_count for every user and then it will be inserted to the "purchase_mis" table.
INSERT INTO
purchase_mis(user_id, total_purchased, date)
VALUES
('2', 'purchase_count', 'purchase_date');
But before inserting, it needs to check if the purchased information of user_id = 2 for some date "purchase_date" has already been inserted so it should not be inserted again.
I want something like the below query:
INSERT INTO
purchase_mis(user_id, total_purchased, date)
VALUES
('2', 'purchase_count', 'purchase_date')
WHERE date NOT EXISTS (SELECT date FROM purchase_mis WHERE user_id = '2');
Create a key on the date column, and then use INSERT IGNORE or INSERT ... ON DUPLICATE KEY UPDATE syntax. See this for more: "INSERT IGNORE" vs "INSERT ... ON DUPLICATE KEY UPDATE"
Also, you can probably use triggers or procedures instead of a cron job; might make life a bit easier.
insert into purchase_mis
(user_id, total_purchased, date)
select *
from (
select 2 as id,
100 as user_id,
str_to_date('2012-12-04', '%Y-%m-%d') as purchase_date
) t
where not exists (SELECT 1
FROM purchase_mis pm
WHERE pm.user_id = t.id
and pm.date = t.purchase_date);