Reputation: 592
I have a table with a set of data like
record_date | id | category | model | name | alternate_name
-------------------------------------------------------------------
9/1/2012 | N42 | X | ABC | blah | blah
10/1/2011 | N42 | Y | No Code | #N/A | #N/A
6/1/2012 | N42 | X | DEF | xxxx | yyyy
7/1/2011 | N42 | Z | No Data | #N/A | #N/A
Since the dataset is not complete I want to fill the missing data (model, name, alternate_name) with data from the most recent record containing data matching on the id field.
i.e. I want it to look something like this
record_date | id | category | model | name | alternate_name
-------------------------------------------------------------------
9/1/2012 | N42 | X | ABC | blah | blah
10/1/2011 | N42 | Y | ABC | blah | blah
6/1/2012 | N42 | X | DEF | xxxx | yyyy
7/1/2011 | N42 | Z | ABC | blah | blah
Upvotes: 0
Views: 204
Reputation: 592
Thank you for the suggestions however neither seemed to work quite right. I ended up doing this in two steps.
use myDB;
drop table if exists tmp_myTable;
create temporary table tmp_myTable like myTable;
insert into tmp_myTable select * from myTable as t1
where record_date in (select max(record_Date)
from myTable where id=t1.id
and (model!="No Code" or model="No Data")
and name!="#N/A")
and (category="X"
or category="Y"
or category="Z")
and (model!="No Code" or model="No Data")
and name!="#N/A";
update myTable as t1 join tmp_myTable as t2 on t1.id=t2.id
set t1.model=t2.model,
t1.name=t2.name,
t1.alternate_name=t2.alternate_name
where (t1.category="X"
or t1.category="Y"
or t1.category="Z")
and (t1.model="No Code" or t1.model="No Data")
and t1.name="#N/A";
Upvotes: 0
Reputation: 1269563
Here is one method that uses three correlated subqueries:
update "table" t
set model = (select model from "table" t2 where t2.id = t.id and t2.record_date < t.record_date and model <> 'No Code' order by t2.record_date limit 1),
name = (select name from "table" t2 where t2.id = t.id and t2.record_date < t.record_date and name <> '#N/A' order by t2.record_date limit 1),
alternate_name = (select alternate_name from "table" t2 where t2.id = t.id and t2.record_date < t.record_date and alternate_name <> '#N/A' order by t2.record_date limit 1)
where model = 'No Code' and name = '#N/A' and alternate_name = '#N/A';
I would recommend that you have a unique id on each row.
Upvotes: 1
Reputation: 7187
Assuming you mean NULL
by no data you can use these query to update one column. You can replace the IS NULL
with something like = "No Data"
UPDATE tableName A JOIN tableName B ON A.id = B.id
SET A.dummyID = B.dummyID
WHERE A.dummyID IS NULL AND B.dummyID IS NOT NULL;
see example
You should run similar queries for other columns. You may combine such queries into one but it will complicate the query and make it less readable.
Say you have another column called anotherColumn
and the "N/A"
means no data, you can use following query -
UPDATE tableName A JOIN tableName B ON A.id = B.id JOIN tableName C ON A.id = C.id
SET A.dummyID = B.dummyID, C.anotherColumn = B.anotherColumn
WHERE A.dummyID IS NULL AND B.dummyID IS NOT NULL AND
C.anotherColumn = "N/A" AND B.anotherColumn <> "N/A";
See example
Upvotes: 0