I Have a table of random names, simply 3 columns(id, firstname, lastname).
I am trying to have SQL update an entire table of names with a random selected name from this table.
Here is the SQL i am using. It seems to work for some of the records, but it doesn't always do all of them, sometime leaving NULLS, or not always updating all rows. Sometime it runs affecting 9 rows, other times it says affected 11 rows... thoughts?
update TestNames,rndnames
set TestNames.fname = rndnames.FirstName,TestNames.lname=rndnames.LastName
where rndnames.ID=floor(1+(rand()*600))
answer:
update
TestNames left join
(select ID,
floor(1+(rand()*600)) as rndid
from TestNames) as TN on TN.ID=TestNames.id
left join rndnames on TN.rndid=rndnames.id
set TestNames.fname=rndnames.FirstName,TestNames.lname=rndnames.LastName
Here is the query:
update TestNames t cross join
rndnames r
set t.fname = r.FirstName,
t.lname = r.LastName
where r.ID = floor(1+(rand()*600));
It only updates a row in testnames when the random id chosen by the expression matches an id in the table. Are the id values in rndnames all populated?
If your table is not very big and it has an id, here is another approach:
update TestName t join
(select t.*,
(select id from rndnames order by rand() limit 1) as rndid
from testname t
) tr
on t.id = tr.id join
rndnames r
on t.rndid = r.id
set t.fname = r.FirstName,
t.lname = r.LastName;
EDIT:
I think this will also work:
update TestNames t cross join
rndnames r
set t.fname = r.FirstName,
t.lname = r.LastName
where r.ID = (select id
from rndnames
order by rand()
limit 1
);
update
TestNames left join
(select ID,
floor(1+(rand()*600)) as rndid
from TestNames) as TN on TN.ID=TestNames.id
left join rndnames on TN.rndid=rndnames.id
set TestNames.fname=rndnames.FirstName,TestNames.lname=rndnames.LastName
Related
I have bd hf3 and 5 tables there:
active_preset with columns (id , preset_id)
preset with columns (id , birja_id, trend_id, fractal, interval_up)
birja with columns (id , name)
trend with columns (id , name)
uq_active_preset with columns (id , birja, trend, fractal, interval_up)
In table preset I have a few records. Some of them are in table active_preset by foreign key preset_id. In table active_preset a few records exist once , a few more than once.
I need to update table uq_active_preset with records from table active_preset disregarding repetitions of records if they are present.
I did query from active_preset and it works good:
SELECT
b.name AS birja, p.fractal AS fractal , tre.name AS trend, p.interval_up AS interval_up
FROM hf3.active_preset AS ap
INNER JOIN hf3.preset AS p on p.id = ap.preset_id
INNER JOIN hf3.birja AS b on b.id = p.birja_id
INNER JOIN hf3.trend AS tre on tre.id = p.trend_id
GROUP BY b.name, p.fractal, tre.name, p.interval_up
HAVING COUNT(*) >= 1
But I don't know how to update uq_active_preset
I tried this and it returns syntax error:1064 :
UPDATE hf3.uq_active_preset uap SET
uap.birja = st.birja ,
uap.fractal = st.fractal,
uap.trend = st.trend,
uap.interval_up = st.interval_up,
FROM (SELECT b.name AS birja, p.fractal AS fractal , tre.name AS trend, p.interval_up AS interval_up
from hf3.active_preset AS ap
INNER JOIN hf3.preset AS p on p.id = ap.preset_id
INNER JOIN hf3.birja AS b on b.id = p.birja_id
INNER JOIN hf3.trend AS tre on tre.id = p.trend_id
GROUP BY b.name, p.fractal, tre.name, p.interval_up
HAVING COUNT(*) >= 1
) st
when you make an update using from is like you join the updated table with your query result. So, you need also a where statement in order to tell where those two are connected. Also, don't use alias of your updated table on set statement.
You need something like that:
UPDATE hf3.uq_active_preset uap SET birja=st.birja,fractal=st.fractal,trend=st.trend,interval_up=st.interval_up
FROM (SELECT b.name AS birja, p.fractal AS fractal , tre.name AS trend, p.interval_up AS interval_up
from hf3.active_preset AS ap
INNER JOIN hf3.preset AS p on p.id = ap.preset_id
INNER JOIN hf3.birja AS b on b.id = p.birja_id
INNER JOIN hf3.trend AS tre on tre.id = p.trend_id
GROUP BY b.name, p.fractal, tre.name, p.interval_up
HAVING COUNT(*) >= 1
) st
where uap.fkey=st.fkey
I have a table refs with citations (AU NAMES, which are separated by ; in one field authors)
and a table called aunames with the AU-NAMES at each row. Now I would like to
update my table aunames with the total number of authors for each citation.
rec ID NAME AUCOUNT
1 3 AU1
2 3 AU2
...
...
How can I do that? (auname_copy is a copy of auname.)
I tried:
update aunames
set aucount = (select count(rec)
from refs
join aunames_copy on refs.id=aunames_copy.id
GROUP BY refs.id) ;
But I get the error:
[Err] 1242 - Subquery returns more than 1 row
WHen I try only one row it works.
update aunames
set aucount = (select count(rec)
from refs
join aunames_copy on refs.id=aunames_copy.id
where refs.id='1'
GROUP BY refs.id )
where id='1';
How can I loop through all rows?
Thanks
You can use the UPDATE ... JOIN ... SET syntax:
UPDATE aunames a
INNER JOIN (
SELECT r.id, count(rec) cnt
FROM refs r
INNER JOIN aunames_copy c ON r.id = c.id
GROUP BY r.id
) x ON x.id = a.id
SET a.aucount = x.cnt
NB: if, as commented by #MadhurBhaiya, you created table aunames_copy as a copy of original table aunames, your query can probably be simplified as:
UPDATE aunames a
INNER JOIN (SELECT id, count(rec) cnt FROM refs GROUP BY id) x ON x.id = a.id
SET a.aucount = x.cnt
I have a query like this -
UPDATE ACTION a
INNER JOIN subscriberinfo s ON a.subscriberId = s.id AND a.subscriberId=118
INNER JOIN ticket t ON t.subscriberId = s.id AND s.id=118
SET a.exceedusage = (SELECT FORMAT(((SUM(dataVolumeDownLink + dataVolumeUpLink))/1048576),2)
FROM cdr c
WHERE c.msisdn =12424474969
AND c.msisdn = s.msisdn
AND c.eventDate>t.cdrEventDate
AND c.eventDate < a.actionTakenOn)
WHERE a.remark='Reason : Data limit crossed'
AND a.exceedusage IS NULL;
I want to update action tables column, am I doing something wrong in this query?
Please explain me with an example that how to perform such kind of update,if possible.
Please, use group by where aggregate function is there:
UPDATE ACTION a
INNER JOIN subscriberinfo s ON a.subscriberId=118
INNER JOIN ticket t ON s.id=118
SET a.exceedusage = (SELECT FORMAT(((SUM(dataVolumeDownLink + dataVolumeUpLink))/1048576),2)
FROM cdr c
WHERE c.msisdn =12424474969
AND c.eventDate>t.cdrEventDate
AND c.eventDate < a.actionTakenOn group by c.msisdn )
WHERE a.remark='Reason : Data limit crossed'
AND a.exceedusage IS NULL;
I have the following query:
SELECT int_intrebari.id, COUNT( id_raspuns ) AS nr_raspunsuri
FROM int_intrebari, int_raspunsuri
WHERE int_intrebari.id = int_raspunsuri.id
GROUP BY id
Is it possible to update first table with nr_raspunsuri from the query, without writing a foreach statement?
You can UPDATE with JOIN like so:
UPDATE int_intrebari i1
INNER JOIN
(
SELECT id, COUNT( id_raspuns ) AS nr_raspunsuri
FROM int_intrebari
GROUP BY id
) i2 ON i1.id = i2.id
SET i1.nr_raspunsuri = i2.nr_raspunsuri
You can do it like -
update int_intrebari left join int_raspunsuri on int_intrebari.id =int_raspunsuri.id
set int_intrebari.column_to_update = int_raspunsuri.column_from_update_second_table
UPDATE
(SELECT int_intrebari.id, COUNT( id_raspuns) AS nr_raspunsuri
FROM int_intrebari, int_raspunsuri
WHERE int_intrebari.id = int_raspunsuri.id
GROUP BY id) t1,
int_raspunsuri t2
SET
t2.nr_raspunsuri=t1.nr_raspunsuri
WHERE
t1.id=t2.id
I have a correlated subquery that will return a list of quantities, but I need the highest quantity, and only the highest. So I tried to introduce an order by and a LIMIT of 1 to achieve this, but MySQL throws an error stating it doesn't yet support limits in subqueries. Any thoughts on how to work around this?
SELECT Product.Name, ProductOption.Name, a.Qty, a.Price, SheetSize.UpgradeCost,
FinishType.Name, FinishOption.Name, FinishTierPrice.Qty, FinishTierPrice.Price
FROM `Product`
JOIN `ProductOption`
ON Product.idProduct = ProductOption.Product_idProduct
JOIN `ProductOptionTier` AS a
ON a.ProductOption_idProductOption = ProductOption.idProductOption
JOIN `PaperSize`
ON PaperSize.idPaperSize = ProductOption.PaperSize_idPaperSize
JOIN `SheetSize`
ON SheetSize.PaperSize_idPaperSize = PaperSize.idPaperSize
JOIN `FinishOption`
ON FinishOption.Product_idProduct = Product.idProduct
JOIN `FinishType`
ON FinishType.idFinishType = FinishOption.Finishtype_idFinishType
JOIN `FinishTierPrice`
ON FinishTierPrice.FinishOption_idFinishOption = FinishOption.idFinishOption
WHERE Product.idProduct = 1
AND FinishTierPrice.idFinishTierPrice IN (SELECT FinishTierPrice.idFinishTierPrice
FROM `FinishTierPrice`
WHERE FinishTierPrice.Qty <= a.Qty
ORDER BY a.Qty DESC
LIMIT 1)
This is a variation of the greatest-n-per-group problem that comes up frequently.
You want the single row form FinishTierPrice (call it p1), matching the FinishOption and with the greatest Qty, but still less than or equal to the Qty of the ProductOptionTier.
One way to do this is to try to match a second row (p2) from FinishTierPrice that would have the same FinishOption and a greater Qty. If no such row exists (use an outer join and test that it's NULL), then the row found by p1 is the greatest.
SELECT Product.Name, ProductOption.Name, a.Qty, a.Price, SheetSize.UpgradeCost,
FinishType.Name, FinishOption.Name, FinishTierPrice.Qty, FinishTierPrice.Price
FROM `Product`
JOIN `ProductOption`
ON Product.idProduct = ProductOption.Product_idProduct
JOIN `ProductOptionTier` AS a
ON a.ProductOption_idProductOption = ProductOption.idProductOption
JOIN `PaperSize`
ON PaperSize.idPaperSize = ProductOption.PaperSize_idPaperSize
JOIN `SheetSize`
ON SheetSize.PaperSize_idPaperSize = PaperSize.idPaperSize
JOIN `FinishOption`
ON FinishOption.Product_idProduct = Product.idProduct
JOIN `FinishType`
ON FinishType.idFinishType = FinishOption.Finishtype_idFinishType
JOIN `FinishTierPrice` AS p1
ON p1.FinishOption_idFinishOption = FinishOption.idFinishOption
AND p1.Qty <= a.Qty
LEFT OUTER JOIN `FinishTierPrice` AS p2
ON p2.FinishOption_idFinishOption = FinishOption.idFinishOption
AND p2.Qty <= a.Qty AND (p2.Qty > p1.Qty OR p2.Qty = p1.Qty
AND p2.idFinishTierPrice > p1.idFinishTierPrice)
WHERE Product.idProduct = 1
AND p2.idFinishTierPrice IS NULL