【发布时间】:2014-05-25 07:40:12
【问题描述】:
我确信那里可能有答案,但我已经搜索了一个月,但找不到方法。
我有一个翻译表:ID、Resource_Object、Resource_Name、Resource_Value、Culture_name、idMinCopy。
当页面更改时,新对象会自动出现,并且函数会检查另一个对象是否具有相同的翻译以将其复制到新对象。
当 Culture_name 为“ES”、“EN”或“Neutral”时,我需要一个 SQL,它允许我检查现有对象并在具有相同 Resource_Value 的对象之间复制语言
中性是一个页内 ID,对于每个culture_name 可以是唯一的,与“EN”相同或与“ES”相同。是唯一保证存在的 Culture_Name,因为它是自动生成的。
我已经为测试表设置了一个 sql fiddle:http://sqlfiddle.com/#!3/d1f52/1
例子:
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
这是一个小样本,我们可以有很多重复和不同的语言。应占优势的值始终是具有较低 [id] 的值。 由于任何对象的唯一保证现有 [culture_name] 是“中性”,我所做的是将“中性”[Resource_Value] 与所有其他“中性”、“ES”和“EN”[Resource_Value] 进行比较 我设法在第一个对象中获取了“CAT”值,但不确定如何将“FR”放入第二个对象中。
期望的结果:
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
我想在 [idMinCopy] 字段中输入最低相同对象的 ID。稍后,如果对任何“Resource_value”进行更改,我可以使用相同的“idMinCopy”轻松更新所有内容。
我想我需要一个递归 cte 和一个 Merge 语句来实现这一点,但我无法使其工作并且不知道还能做什么。
我检查过的可能相关的资源(显示为代码,因为我没有代表。):
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
我现在使用的sql:
--- 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'
我绝对确定这已经在某个地方解决了,但我一直无法找到或采用找到的解决方案。
感谢您的帮助。
【问题讨论】:
-
在这里我会非常谨慎 - 谨防同音异义词。仅仅因为两个项目在两个地方被翻译成相同的字符串,并不意味着它们具有完全相同的含义,因此适合其中一个的更改可能不适合另一个。
-
对不起,这里的数据太多,所以有点难以理解。让我在这里总结一下你的问题。您需要 Resource_Value 和 Culture_Name 组合的 id。如果此组合重复,您想为新组合提供相同的 id,否则您想生成一个新的 id。我在这里还是我错过了什么?
-
@Damien_The_Unbeliever 感谢您的提示,我正在使用 Neutral 来避免这个问题。一旦字符串的自动匹配完成,我可以手动编辑中性以避免将来匹配。当我说手动时,我的意思是我有一个后台屏幕,我可以在其中检查一个对象并说不自动匹配它。英语不是我的语言,所以也许我没有正确解释它。感谢您的帮助!
-
@samar 我想要 Resource_Value 和 Culture_name='Neutral' 的 id。如果此组合重复或此 Resource_Value 和 Culture_Name='ES' 或 Culture_Name='EN' 的组合,那么我想使用最旧对象的所有值更新最新的对象(对象是相同的 RESOURCE_NAME 和 RESOURCE_OBJECT,许多 CULTURE_NAMEs)。并在两个对象中插入缺少的 RESOURCE_VALUES 及其 CULTURE_NAME。最新的对象是其 NEUTRAL 值中 ID 较高的对象。
-
@samar 我可能想多了,因为我不是数据库专家,也许还有另一个我没有想到的解决方案。随意提出解决方案的任何其他方向。
标签: c# sql sql-server sql-server-2008 tsql