【问题标题】:SQL find missing language entries in tableSQL 查找表中缺少的语言条目
【发布时间】:2015-06-30 04:16:10
【问题描述】:

我有一张表缺少某些特定语言的条目。如何获取缺少外语翻译对应项(lang 2)的所有英语语言文本列表(表中的 lang 1)

我的表如下

PageName | LanguageNo | TranslationName | TranslationText   |
main     |     1      | SomeName        | some english text |
main     |     2      | SomeName        | some foreign text |
main     |     1      | SomeName2       | some english 2    |
other    |     1      | SomeName3       | some english 3    |
other    |     2      | SomeName3       | some foreign 3    |

例如,使用上面的表格数据,应该只返回以下内容:

main     |     1      | SomeName2       | some english 2    |

如何编写 SQL 语句来实现这一点?

谢谢

【问题讨论】:

  • 首先,您使用的是什么 DBMS?然后自己尝试一些东西,如果你不成功,发布代码,以便人们可以对其进行调试。
  • 抱歉我的朋友,我在 MS SQL Management Studio 上使用 T-SQL。
  • LanguageNo 和 TranslationName 是键?
  • 该表使用 PageName、LanguageNo 和 TranslationName 作为复合键
  • 感谢您的评论。我在下面创建了一个示例代码 - 包括语句的输入/输出

标签: sql sql-server tsql


【解决方案1】:

您可以尝试以下方法:

-- Create demo data
CREATE TABLE #translation(pageName nvarchar(10), LanguageNo int, TranslationName nvarchar(25), TranslationText nvarchar(50))

INSERT INTO #translation(pageName, LanguageNo, TranslationName, TranslationText)
VALUES  ('main',1,'SomeName','some english text'),
        ('main',2,'SomeName','some foreign text'),
        ('main',1,'SomeName2','some english 2'),
        ('other',1,'SomeName3','some english 3'),
        ('other',2,'SomeName3','some foreign 3')
        --,('other',3,'SomeName3','some foreign 3') -- uncomment for language3 demo

-- your work:
SELECT availTrans.*
FROM #translation t
-- get all needed combinations
RIGHT JOIN(
        SELECT DISTINCT t.pageName, t.TranslationName, langs.LanguageNo
        FROM #translation as t
        CROSS JOIN (SELECT DISTINCT LanguageNo FROM #translation) as langs
    ) as availTrans
    ON t.pageName = availTrans.pageName
    AND t.TranslationName = availTrans.TranslationName
    AND t.LanguageNo = availTrans.LanguageNo
WHERE t.pageName IS NULL

-- Cleanup
DROP TABLE #translation

给定输入:

pageName   LanguageNo  TranslationName           TranslationText
---------- ----------- ------------------------- ---------------------
main       1           SomeName                  some english text
main       2           SomeName                  some foreign text
main       1           SomeName2                 some english 2
other      1           SomeName3                 some english 3
other      2           SomeName3                 some foreign 3

产生这个结果:

pageName   TranslationName           LanguageNo
---------- ------------------------- -----------
main       SomeName2                 2

【讨论】:

  • 起初我认为这过于复杂。然后我意识到,当存在多种“外语”语言时,这是唯一解决查找缺失翻译的解决方案。添加一些 LanguageNo=3 的行以查看此内容。
  • 我在演示中添加了一种语言 3,默认情况下它被注释掉了,因为 OP 没有提供它。是的,此解决方案适用于独立数量的语言。我很确定标记的答案不是解决方案。
【解决方案2】:

有几种方法,但这里有一种使用not exists

select t.*
from mytable t
where t.LanguageNo = 1 and
      not exists (select 1
                  from mytable t2
                  where t2.pagename = t.pagename and 
                        t2.translationname = t.translationname and
                        t2.LanguageNo = 2
                 );

Here 是一个 SQL Fiddle。

【讨论】:

  • 我很确定这不会产生预期的结果。我已经用给出的演示数据对其进行了测试。 (您可以在我的回答中使用我的表结构自行测试)
  • @Ionic 。 . .谢谢你。答案是固定的。
  • 很高兴为您提供帮助。 :-)
【解决方案3】:

您也可以像这样使用SUMOVER()

查询

;WITH CTE AS
(
    SELECT pageName, LanguageNo, TranslationName, TranslationText,
    SUM(CASE WHEN LanguageNo = 1 THEN 1 ELSE 0 END) OVER(PARTITION BY TranslationName) L1,
    SUM(CASE WHEN LanguageNo = 2 THEN 1 ELSE 0 END)  OVER(PARTITION BY TranslationName) L2
    FROM #translation t
)
SELECT pageName, LanguageNo, TranslationName, TranslationText FROM CTE
WHERE L1 >=1 AND L2 = 0

输出

pageName    LanguageNo  TranslationName TranslationText
main    1   SomeName2   some english 2

【讨论】:

  • 是的,但请注意,这仅适用于 2 种语言。如果随着时间的推移你有更多的语言,它需要适应:)
【解决方案4】:
SELECT t1.*
  FROM tblTranslation t1
  LEFT JOIN tblTranslation t2 
    ON t2.TranslationName = t1.TranslationName        
   AND t2.LanguageNo = 2
 WHERE t2.TranslationName IS NULL
   AND t1.LanguageNo = 1

【讨论】:

  • 这也会返回 LanguageNo 1 的所有内容。
  • 查看将 t1.LanguageNo = 1 移到哪里
【解决方案5】:
SELECT t1.*
FROM tblTranslation t1
LEFT JOIN tblTranslation t2 ON t2.PageName = t1.PageName  
                            AND t2.TranslationName = t1.TranslationName 
                            AND t2.LanguageNo = 2
WHERE t1.LanguageNo = 1
AND t2.LanguageNo IS NULL

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多