I'm sure that there may be an answer out there but I've been searching for a month now and can't find how to do it.
I have a table for translations with: ID, Resource_Object, Resource_Name, Resource_Value, Culture_name, idMinCopy.
New objects appear automatically when the page is changed and a function checks if another object has an identical translation to copy it to the new object.
What I need is an SQL that allows me to check the existing objects and copy languajes between objects with same Resource_Value when Culture_name is either 'ES', 'EN' or 'Neutral'
Neutral is an in-page ID that can be unique for every culture_name, identic to 'EN' or identic to 'ES'. Is the only Culture_Name that is guaranteed to exist as it's auto-generated.
I've put up a sql fiddle with the test table: http://sqlfiddle.com/#!3/d1f52/1
Example:
ID Resource_Object Resource_Name Resource_Value Culture_Name idMinCopy
--------------------------------------------------------------------------
1 |home.aspx |label1.text |Blue |Neutral |Null
2 |home.aspx |label1.text |Blue |EN |Null
3 |home.aspx |label1.text |Azul |ES |Null
4 |home.aspx |label1.text |Bleu |FR |Null
5 |page1.aspx |lblColor.text |Azul |Neutral |Null
6 |page1.aspx |lblColor.text |Blue |EN |Null
7 |page1.aspx |lblColor.text |Azlu |ES |Null
8 |page1.aspx |lblColor.text |Blau |CAT |Null
9 |page1.aspx |lblTitle.text |Color |Neutral |Null
10 |page1.aspx |lblTitle.text |Color |ES |Null
11 |page1.aspx |lblTitle.text |Colour |EN |Null
This is a small sample, we can have many duplicates and different languajes. The value that should prevail is always the one with the lower [id]. As the only guaranteed existing [culture_name] for any object is 'neutral', what I do is compare 'neutral' [Resource_Value] with all other 'Neutral', 'ES' and 'EN' [Resource_Value] I've managed to get the 'CAT' values in the first object but not sure of how to put the 'FR' in the second object.
Desired Result:
ID Resource_Object Resource_Name Resource_Value Culture_Name idMinCopy
--------------------------------------------------------------------------
1 |home.aspx |label1.text |Blue |Neutral |1
2 |home.aspx |label1.text |Blue |EN |2
3 |home.aspx |label1.text |Azul |ES |3
4 |home.aspx |label1.text |Bleu |FR |4
5 |page1.aspx |lblColor.text |Blue |Neutral |1
6 |page1.aspx |lblColor.text |Blue |EN |2
7 |page1.aspx |lblColor.text |Azul |ES |3
8 |page1.aspx |lblColor.text |Blau |CAT |12
9 |page1.aspx |lblTitle.text |Color |Neutral |Null
10 |page1.aspx |lblTitle.text |Color |ES |Null
11 |page1.aspx |lblTitle.text |Colour |EN |Null
12 |home.aspx |label1.text |Blau |CAT |12
13 |page1.aspx |lblColor.text |Bleu |FR |4
I want to put in the [idMinCopy] field the ID of the lowest identical object. Later if a change is made in any 'Resource_value' I can easily update all with the same 'idMinCopy'.
I guess I need a recursive cte and a Merge statement to achieve this but I'm not able to make it work and not know what else to do.
Resources I've checked that may be related (Shown as code as I've no rep.):
http://stackoverflow.com/questions/21216534/sql-query-result-from-multiple-tables-without-duplicates
http://stackoverflow.com/questions/12910287/merging-tables-with-duplicate-data
http://stackoverflow.com/questions/14274942/sql-server-cte-and-recursion-example
http://www.codeproject.com/Articles/683011/How-to-use-recursive-CTE-calls-in-T-SQL
http://stackoverflow.com/questions/1222581/how-get-the-t-sql-code-to-find-duplicates
http://pratchev.blogspot.com.es/2008/03/upsert-and-more-with-merge.html
http://www.sergeyv.com/blog/archive/2010/09/10/sql-server-upsert-equivalent.aspx
The sql I'm using now :
--- Search for similar 'Resource_Values'
--- returns identical object with lowest ID
DECLARE @textoprueba as nvarchar(1000)
set @textoprueba='Blue'
select top 1
case when t2.id is not null then t1.id end as t2id
from tbtraducciones t1 LEFT join tbtraducciones t2
on t1.resource_value = t2.resource_value AND (t1.culture_name='neutral' OR t1.culture_name='en' OR t1.culture_name='es')
AND t2.culture_name='neutral' AND (t1.Resource_name != t2.Resource_NAME OR t1.RESOURCE_OBJECT != t2.RESOURCE_OBJECT)
where case when t2.id is not null then t2.id end is not null
and t2.resource_value=@textoprueba order by t1.id
--- Search for the ID of the 'Neutral' value for that object
DECLARE @minID as int
set @minID=[Result from previous SQL Statement]
select id from tbTraducciones
where resource_name = (select resource_name from tbtraducciones where id=@minId)
and resource_object= (select resource_object from tbtraducciones where id=@minId)
and culture_name = 'neutral'
---UPSERT DUPLICATES
DECLARE @idNeutral as int, @newId as Int
set @newID=[ID of the object with same 'Resource_Value' with higher ID]
set @idNeutral= [ID of the lowest id 'neutral' that has the same 'Resource_Value' in 'Neutral', 'ES' or 'EN']
;WITH T AS
(
select
t1.Resource_object , t1.Resource_name as Resource_Name, t3.Resource_Value AS RESOURCE_VALUE,
t3.Culture_Name AS CULTURE_NAME, t3.Id AS idMinCopy
from tbTraducciones t1
JOIN tbTraducciones t2 on t2.id=@idNeutral
right join tbTraducciones t3 on t3.Resource_Object = t2.Resource_Object AND t3.Resource_Name = t2.Resource_Name
where t1.id=@newID and
t3.culture_NAME <> 'Neutral'
)
UPDATE tbTraducciones SET
[RESOURCE_VALUE]=T.Resource_Value ,
[idMinCopy] = T.idMinCopy
FROM T
WHERE T.Resource_Object = tbTraducciones.Resource_Object
AND
tbTraducciones.Resource_Name = T.Resource_Name
AND
tbTraducciones.Culture_Name = T.Culture_Name
IF @@ROWCOUNT=0
INSERT INTO [tbTraducciones] (Resource_Object, Resource_Name, Resource_Value, Culture_Name, idMinCopy)
select t1.Resource_object, t1.Resource_name, t3.Resource_Value, t3.Culture_Name, t3.Id
from tbTraducciones t1
JOIN tbTraducciones t2 on t2.id=@idneutral
join tbTraducciones t3 on t3.Resource_Object = t2.Resource_Object AND t3.Resource_Name = t2.Resource_Name
where t1.id=@newID and t3.Culture_Name !='Neutral'
I'm absolutly sure that this has been resolved before somewhere, but I've been unable to find or adopt the solutions found.
Thank you for your Help.