Issue with updating a table - mysql

I have this table
What I want to do is that Select the attr_id WHERE a DISTINCT name_en-GB appears and then SET that selected attr_id for that name_en-GB
I can do this by writing individual queries but I want to know is there any way I can do this in one query?

You can do
UPDATE table1
SET attr_id = CASE `name_en-GB` WHEN 'Bride Name' THEN 142
WHEN 'Child Grade' THEN 270 END
WHERE `name_en-GB` IN('Bride Name', 'Child Grade')
Here is SQLFiddle demo

you can do this simply with an update query and a select.. however I don't know what is the criteria for the first appearence of an attr_id
assumption - first appearance is by the smallest attr_id
UPDATE table t,
( SELECT MIN(attr_id), `name_en-GB`
FROM table
GROUP BY `name_en-GB`
) t1
SET t.attr_id = t1.attr_id
WHERE t1.`name_en-GB` = t.`name_en-GB`

I have finally done this
UPDATE sc_product_phrase
JOIN (
SELECT
`caption`,
min(design_phrase_id) AS minai,
required
FROM
sc_product_phrase WHERE LENGTH(`options`) < 1
GROUP BY
`caption`
) tt ON sc_product_phrase.`caption` = tt.`caption`
AND sc_product_phrase.required = tt.required
SET design_phrase_id = tt.minai
WHERE
sc_product_phrase.design_phrase_id <> tt.minai
AND LENGTH(
sc_product_phrase.`options`
) < 1

Related

How to delete only a single row from 2 duplicate rows?

I have 2 duplicate rows in the table,I want to delete only 1 from that and keep the other row.how can I do that?
The PostGres code might be a little different, but here's an example from TSQL that does it with a CTE:
; WITH duplicates
AS (
SELECT ServerName ,
ProcessName ,
DateCreated ,
RowRank = ROW_NUMBER() OVER(PARTITION BY ServerName, ProcessName, DateCreated ORDER BY 1)
FROM dbo.ErrorLog
)
DELETE e
FROM dbo.ErrorLog e
JOIN duplicates d
ON d.ServerName = e.ServerName
AND d.ProcessName = e.ProcessName
AND d.DateCreated = e.DateCreated
AND d.RowRank <> 1

MS SQL query with multiple search criteria across rows

I have below table and SQL query written, this query should not return any result but its returning ID = 1 , what is wrong with the SQL query? Can anyone please help?
** Note balance data type is decimal rest are varchar
ID code balance level
1 C 150.00
1 P 40027.42 F
1 P 40027.42 F
select distinct ID from table
(
(code = 'P' and balance = 40027.42 and level = 'F') or
(code = 'C' and balance = 151.00 )
)
group by ID
having count(ID) >=2
If you do not want to count the same code twice, you can use count(distinct code):
select ID
from t
where (code = 'P' and balance = 40027.42 and level = 'F')
or (code = 'C' and balance = 151.00 )
group by ID
having count(distinct code) >=2
If you want to only count a distinct set of values once, you can use a derived table/subquery to select distinct rows:
select ID
from (
select distinct id, code, balance, level
from t
) as s
where (code = 'P' and balance = 40027.42 and level = 'F')
or (code = 'C' and balance = 151.00 )
group by ID
having count(ID) >=2
rextester demo for both: http://rextester.com/LBKO57534

MySQL rows with maximum and specific values

I have to write a query to retrieve data from a table, using the selected date and selected category. I have written a query and it does not give correct data as expected. It should query only rows with maximum actiondate, if the action column has the value 'AD'.
INSERT INTO goldstockvaluation SELECT sh.stockid, sh.description, sh.branch, sh.grossweight, sh.pureweight, sh.purity, sh.goldcarat, sh.mcpergram, sh.goldpergram, sh.fixgold, CURDATE( )
FROM stock_history sh
JOIN (
SELECT stockid, branch,ACTION , MAX( actiondate ) AS MaxDateTime
FROM stock_history
GROUP BY stockid,branch,ACTION
)groupedsh ON sh.stockid = groupedsh.stockid
AND sh.actiondate = groupedsh.MaxDateTime
AND sh.branch = groupedsh.branch
AND sh.action = groupedsh.action
AND sh.branch = '8'
AND sh.categoryid = 'G'
AND sh.action = 'AD'
AND sh.actiondate <= '2016-03-28 23:59:59'
This is to query out the rows that have action as 'AD' and have the max(actiondate).
To query with max(action_date), you need to use sub query, e.g.:
select field1, field2
from table
where
sh.action = 'AD'
and sh.actiondate = (
select max(sh.actiondate)
from table
where sh.action = 'AD'
);

How to use mysql subquery with a where clause in a where clause that requires data from the superquery

i'm going to try this:
SELECT
Bestellung.ID BNr,
RechnAddr Kunde,
(SELECT
Name
FROM `User`
WHERE ID = Bestellung.SalesPerson) Verkaeufer,
Clerk Sachbearbeiter,
(SELECT
Ort
FROM `Location`
WHERE ID = Bestellung.Location) Standort,
CONCAT_WS('.', LPAD(Day, 2,'0'), LPAD(Month, 2,'0'), Year) Erstelldatum
FROM `Bestellung`
WHERE
SalesPerson != ''
AND
(SELECT COUNT(*) cnt FROM _BestellungsPosition bp
WHERE bp.OrderID = Bestellung.BNr) = 0
i just want all orders that have no order items, but mysql tells me "Unknown column 'Bestellung.BNr' in 'where clause"...
am i using the subquery wrong?!
please help me
edit: i changed the (pseudo) query i used before to the true one, because my pseudo query worked, but the true one with real data didn't
edit2: now i changed the query to:
SELECT
Bestellung.ID BNr,
RechnAddr Kunde,
(SELECT
Name
FROM `User`
WHERE ID = Bestellung.SalesPerson) Verkaeufer,
Clerk Sachbearbeiter,
(SELECT
Ort
FROM `Location`
WHERE ID = Bestellung.Location) Standort,
CONCAT_WS('.', LPAD(Day, 2,'0'), LPAD(Month, 2,'0'), Year) Erstelldatum
FROM `Bestellung` LEFT JOIN _BestellungsPosition bp
WHERE
SalesPerson != ''
AND
bp.Order IS NULL
and it works... thanks to the responder with this hint, but he deleted his answer i think
edit2: now i changed the query to:
SELECT
Bestellung.ID BNr,
RechnAddr Kunde,
(SELECT
Name
FROM `User`
WHERE ID = Bestellung.SalesPerson) Verkaeufer,
Clerk Sachbearbeiter,
(SELECT
Ort
FROM `Location`
WHERE ID = Bestellung.Location) Standort,
CONCAT_WS('.', LPAD(Day, 2,'0'), LPAD(Month, 2,'0'), Year) Erstelldatum
FROM `Bestellung` LEFT JOIN _BestellungsPosition bp
WHERE
SalesPerson != ''
AND
bp.Order IS NULL
and it works... thanks to the responder with this hint, but he deleted his answer i think
You need to specify the IDs to select (or exclude) in a subquery and it may be inefficient. Try this below:
SELECT
ID, Customer, SalesPerson, Clerk, Date
FROM `Order`
WHERE ID NOT IN
(SELECT DISTINCT OrderID FROM OrderItem);

Update multiple rows from same table in mysql

Update a single column over multiple rows depending on the data from the same table.
update table1 set status=newtime
from (
select
case
when TIME_FORMAT( TIMEDIFF( ADDTIME( time_val, '120:00:00' ), NOW() ), '%Hh %im %ss')<0 then '4'
else '0'
end as newtime,
id as new_id
FROM table1
where id2='2'
and status='0'
)
where id=new_id
This is my query. Thanks in advance.
Edit:
This is an alternate query to achieve this. But it also gives me an error
update table1 set status=
(select
case when timeleft<0 then '4' else '0' end as something,
new_id
from
(
select
TIME_FORMAT( TIMEDIFF( ADDTIME( time_val, '120:00:00' ), NOW() ), '%Hh %im %ss') as newtime,
id as new_id
FROM
table1
where id2='2' and
status='0'
)
}
where id=new_id
"#1248 - Every derived table must have its own alias".
I cannot use alias as I am fetching two columns from the query. Any help would be great.
UPDATE statements have no FROM clause in MySQL syntax. However, you can JOIN table against the subquery.
UPDATE
table1 t1
JOIN (
select
case
when TIME_FORMAT( TIMEDIFF( ADDTIME( time_val, '120:00:00' ), NOW() ), '%Hh %im %ss')<0 then '4'
else '0'
end as newtime,
id as new_id
FROM table1
WHERE id2='2' AND status='0'
) tsub ON t1.id = tsub.new_id
SET status = tsub.newtime
It looks to me like you don't need to do any subquerying or joining at all. This should do what you want:
UPDATE table1
SET status = CASE WHEN TIME_FORMAT(TIMEDIFF(ADDTIME(time_val, '120:00:00'), NOW()), '%Hh %im %ss') < 0 THEN '4' ELSE '0' END
WHERE id2 = '2' AND status = '0'
In the query you wrote, your subquery will get back the new time_val and the id number of the row to update, for any rows that match the criteria id2 = '2' AND status = '0'. You will then update all those rows (that matched the above criteria) and set the status to the new time_val.
Instead of selecting them first, cut out the middle man and just update all rows that match that criteria with the new value. Your query will be faster and more straightforward.
Besides the simplified version (provided by #Travesty3), it seems you are using a whole bunch of date and time functions to test for a simple thing:
UPDATE table1
SET status = '4'
WHERE id2 = '2'
AND status = '0'
AND time_val < NOW() - INTERVAL 120 HOUR
We can update table with multiple row by same table or two different table in this manner, just posting a snippet of mysql code from my procedure
Update documentcolumns as tb1, documentcolumns as tb2 set tb1.documentColumnPos = tb2.documentColumnPos Where tb1.userID = user_id and tb2.userID is NULL and tb1.columnNameDefID= tb2.columnNameDefID and tb1.tabtype = tab_type and tb2.tabtype = tab_type;,