I'm trying to recreate some code I did in SQL server on mySQL. I want to insert a row for every row in a table. I am using a loop to do this, in SQL server I used SELECT TOP #foo
here is my mySQl
begin
set #maxloop = (select max(id) from `LeagueInfo`);
set #loopno = 1;
while #loopno <= #maxloop DO
SET #mtop = (select `teams` * `homegames` from `LeagueInfo` where id = #loopno);
SET #div = (select `LeagueShortName` from `LeagueInfo` where id = #loopno);
SET #teams = (select teams from `LeagueInfo` where id = #loopno);
SET #homegames = (select homegames from `LeagueInfo` where id = #loopno);
SET #fthgsum = (select sum(`FTHG`)/#teams/#homegames from `footy` where `id` in(select`id`, `div` from `footy`
where `div` = #DIV
order by `matchdate` desc LIMIT #mtop));
SET #ftagsum = (select sum(`FTAG`)/#teams/#homegames from `footy` where `id` in(select`id`, `div` from `footy`
where `div` = #DIV
order by `matchdate` desc LIMIT #mtop));
insert into `looptable` (`di`, `homeav`, `awayav`) values (#div, #fthgsum,#fthgsum);
set #loopno = #loopno +1;
END while;
END;
I get an error on limit #mtop. I've read that I can get round this with a prepared statement but I'm not sure how to do it in a subquery. Is there a was to do this or is there another was I can select the top x amount of rows based on a value in another table for each row in that table.
Thanks
Paul
In your line of code,
SET #mtop = (select 'teams' * 'homegames' from 'LeagueInfo' where id = #loopno)
mtop is not a number, which is false since limit needs to be a number.
maybe you want to use "count(*)"?
Related
I have read a bunch of ways that has gotten me this far. But I can't get to the finish line.
I have a table of coupon codes. I want to use one transaction to select the next available code, mark it as used and input the order number. I can get the update and nested select to work, but I cannot figure out how to actually return the coupon code from the select. It just returns 1 row updated.
Here's what I've got:
UPDATE `prcoupon` pr
SET
`pr`.`status` = '1',
`pr`.`invoicenumber` = '09990002'
WHERE
`pr`.`couponCode` = (SELECT
`prcoupon`.`couponcode`
FROM
`prcoupon`
WHERE
`status` = 0
LIMIT 1)
Sample data
What I need returned is: couponCode: SL2T-03A0-JVCY-W2XMXG
If I understand correctly, you can try to use UPDATE ... JOIN with ROW_Nunber windwon function.
UPDATE prcoupon pr
JOIN (
SELECT *,ROW_NUMBER() OVER(ORDER BY couponCode) rn
FROM prcoupon
WHERE status = 0
) t2 ON pr.couponcode = t2.couponcode
SET pr.status = 1,
pr.invoicenumber = '09990002'
WHERE rn = 1
sqlfiddle
How do I append a character to all items `purchase_id' here is a manual example of what I want...
SELECT *
FROM `loadable_link`
WHERE `product_sku` = '2101-R'
ORDER BY `customer_id` DESC
Then select from purchased_id and append a '0' to all purchased ID's
UPDATE `loadable_link` SET `purchased_id` = '11165690'
WHERE `loadable_link`.`purchased_id` = 1116569;
You can update the table according to the condition in the original select statement.
If purchase_id is a number, you can multiply it by 10:
UPDATE `loadable_link`
SET `purchase_id` = `purchase_id` * 10
WHERE `product_sku` = '2101-R'
If purchase_id is a string, you can concatenate a 0 to it:
UPDATE `loadable_link`
SET `purchase_id` = CONCAT(`purchase_id`, '0')
WHERE `product_sku` = '2101-R'
UPDATE `loadable_link`
SET `purchased_id` = CONCAT(`purchased_id`, "0")
WHERE `product_sku` = "2101-R";
This can be achieved in one UPDATE query, take the original value of each row and CONCAT() to append a 0 to the end of the existing purchase_id.
table
create table tst(locationId int,
scheduleCount tinyint(1) DEFAULT 0,
displayFlag tinyint(1) DEFAULT 0);
INSERT INTO tst(locationId,scheduleCount)
values(5,0),(2,0),(5,1),(5,2),(2,1),(2,2);
I update multiple rows and multiple columns with one query, but want to change the one of the columns only for the first row and keep the other things the same for that column.
I want to update all the rows with some location id and change displayFlag to 1 and increment scheduleCount of only the top entry with 1 , rest would remain the same
**Query **
update tst,(select #rownum:=0) r,
set tst.displayFlag =1,
scheduleCount = (CASE WHEN #rownum=0
then scheduleCount+1
ELSE scheduleCount
END),
#rownum:=1 where locationId = 5
But it gives error and does not set the user defined variable rownum, I am able to join the tables in a select and change the value of the rownum, is there any other way to update the values.
I'm not sure this is the correct way of doing such a thing, but it is possible to include the user variable logic in the CASE condition:
UPDATE tst
JOIN (SELECT #first_row := 1) r
SET tst.displayFlag = 1,
scheduleCount = CASE
WHEN #first_row = 1 AND ((#first_row := 0) OR TRUE) THEN scheduleCount+1
ELSE scheduleCount
END
WHERE locationId = 5;
I have used a #first_row flag as this is more inline with your initial attempt.
The CASE works as follows:
On the first row #first_row = 1 so the second part of the WHEN after AND is processed, setting #first_row := 0. Unfortunately for us, the assignment returns 0, hence the OR TRUE to ensure the condition as a whole is TRUE. Thus scheduleCount + 1 is used.
On the second row #first_row != 1 so the condition is FALSE, the second part of the WHEN after AND is not processed and the ELSE scheduleCount is used.
You can see it working in this SQL Fiddle. Note; I have had to set the column types to TINYINT(3) to get the correct results.
N.B. Without an ORDER BY there is no guarantee as to what the '1st' row will be; not even that it will be the 1st as returned by a SELECT * FROM tst.
UPDATE
Unfortunately one cannot add an ORDER BY if there is a join.. so you have a choice:
Initialise #first_row outside the query and remove the JOIN.
Otherwise you are probably better off rewriting the query to something similar to:
UPDATE tst
JOIN (
SELECT locationId,
scheduleCount,
displayFlag,
#row_number := #row_number + 1 AS row_number
FROM tst
JOIN (SELECT #row_number := 0) init
WHERE locationId = 5
ORDER BY scheduleCount DESC
) tst2
ON tst2.locationId = tst.locationId
AND tst2.scheduleCount = tst.scheduleCount
AND tst2.displayFlag = tst.displayFlag
SET tst.displayFlag = 1,
tst.scheduleCount = CASE
WHEN tst2.row_number = 1 THEN tst.scheduleCount+1
ELSE tst.scheduleCount
END;
Or write two queries:
UPDATE tst
SET displayFlag = 1
WHERE locationId = 5;
UPDATE tst
SET scheduleCount = scheduleCount + 1
WHERE locationId = 5
ORDER BY scheduleCount DESC
LIMIT 1;
I'm trying to update a table based on 2 select subquery that will be multipied to produce the value for Harga column
here is my code :
UPDATE bahanmakanan
SET Harga = (SELECT HargaSatuan from detail_bahanmakanan
WHERE IDBahanMakanan = "BM01")* (SELECT jumlah from bahanmakanan
WHERE IDBahanMakanan = "BM01")
WHERE IDBahanMakanan = "BM01" ;
The error message return
Error Code: 1093. You can't specify target table 'bahanmakanan' for update in FROM clause
you can simply do this using JOIN,
UPDATE bahanmakanan a
INNER JOIN detail_bahanmakanan b
ON a.IDBahanMakanan = b.IDBahanMakanan
SET a.Harga = a.jumlah * b.HargaSatuan
WHERE a.IDBahanMakanan = 'BM01'
Please do backup first your database before executing the statement.
Try this:
UPDATE bahanmakanan as t1
JOIN detail_bahanmakanan as t2 USING(IDBahanMakanan)
SET t1.Harga = t2.HargaSatuan * t1.jumlah
WHERE IDBahanMakanan = "BM01";
I have a flag in my database called published, I set this to 1 for a published row. My question is , is there a way to set all other rows to 0 and set a particular row to 1 with just one query.
At the moment im using:
$db->query("UPDATE my_table SET published = '0'");
$db->query("UPDATE my_table SET published = '1' WHERE id = '$id'");
UPDATE my_table SET published = IF (id = $id,1,0);
Use a CASE Statement
UPDATE my_table
SET published = CASE
WHEN id = '$id' THEN 1
ELSE 0 END
In MySQL, there's no boolean type (conditions return an integer), so this works too :
UPDATE my_table
SET published = (id = $id);
id = $id returns 0 if $id is different than id, else 1.