Reputation: 5
I have a table with rows which are look like this:
| ID | NAME | LOCALE |
| x | name | en |
| x | name | ru |
| y | name1| en |
| y | name1| ru |
And so on. But some rows are present in just one locale. I need to insert missing rows, so for every ID and NAME there is 2 rows for 2 locales.
Upvotes: 0
Views: 56
Reputation: 520908
Assuming that each name would only ever have two locales present, then here is a straightforward option:
INSERT INTO yourTable (ID, NAME, LOCALE)
SELECT
ID,
NAME,
CASE WHEN LOCALE = 'en' THEN 'ru' ELSE 'en' END
FROM
(
SELECT ID, NAME, MAX(LOCALE) AS LOCALE
FROM yourTable
GROUP BY ID, NAME
HAVING COUNT(*) = 1
) t;
If you actually have more than two locales, then I think we would have to assume that there is some table containing all locales. The query for that case would be more complicated than what I wrote above.
Upvotes: 2
Reputation: 1406
Add missing name entries:
INSERT INTO <YourTable>
(ID, NAME, LOCALE)
(
SELECT t1. ID, 'name', t1.LOCALE
FROM <YourTable> t1
WHERE NOT EXISTS
(
SELECT t2.LOCALE
FROM <YourTable> t2
WHERE t2.NAME = 'name' AND t1.LOCALE = t2.LOCALE
)
)
Add missing name1 entries:
INSERT INTO <YourTable>
(ID, NAME, LOCALE)
(
SELECT t1.ID, 'name1', t1.LOCALE
FROM <YourTable> t1
WHERE NOT EXISTS
(
SELECT t2.LOCALE
FROM <YourTable> t2
WHERE t2.NAME = 'name1' AND t1.LOCALE = t2.LOCALE
)
)
If the strings name and name1 don't play a role, and you just need a second row for any locale whioch exist only once you can use:
INSERT INTO <YourTable>
(ID, NAME, LOCALE)
(
SELECT t1.ID, 'Placeholder for locale', t1.LOCALE
FROM <YourTable> t1
WHERE
(
SELECT COUNT(*)
FROM <YourTable> t2
WHERE t1.LOCALE = t2.LOCALE
) = 1
)
Upvotes: 0
Reputation: 22949
If I understand well, you may need something like the following:
test case:
create table someTable(ID, NAME, LOCALE) as (
select 'x', 'name' ,'en' from dual union all
select 'x', 'name' ,'ru' from dual union all
select 'y', 'name1' ,'en' from dual union all
select 'y', 'name1' ,'ru' from dual union all
select 'z', 'ZZZZ' ,'ru' from dual
)
add missing rows:
merge into someTable s
using(
select *
from
(select 'en' LOCALE from dual union
select 'ru' LOCALE from dual
)
cross join
( select distinct ID, name from someTable)
) x
on (x.id = s.id and x.name = s.name and s.locale = x.locale)
when not matched then
insert values (x.id, x.name, x.locale)
The result:
ID NAME LOCALE
-- ----- ------
x name en
x name ru
y name1 en
y name1 ru
z ZZZZ ru
z ZZZZ en
Upvotes: 0