2015-06-29 2 views
1

У меня есть таблица, в которой отсутствуют некоторые записи для определенного языка. Как я могу получить список всех языков текста на английском языке (языке 1 в таблице), который пропускает иностранный перевод аналог (языки 2)SQL найти недостающие записи языка в таблице

Моя таблица выглядит следующим образом

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 для этого?

Благодаря

+0

Во-первых, что СУБД вы используете ?? И второй попробуйте что-то самостоятельно и опубликуйте код, если вам не удастся, чтобы люди могли отлаживать его. –

+0

Извиняется за моего друга, я использую T-SQL в MS SQL Management Studio. – user2928010

+0

LanguageNo и TranslationName - это ключи? – Ionic

ответ

1

Есть несколько способов, но вот один, который использует 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 Скрипки.

+1

Я уверен, что это не даст желаемого результата. Я тестировал его с данными демо. (Вы можете использовать мою структуру таблицы в своем ответе, чтобы проверить ее самостоятельно) – Ionic

+0

@Ionic. , , Спасибо. Ответ исправлен. –

+0

Приятно вам помочь. :-) – Ionic

2

Вы можете попробовать следующее:

-- 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 
+1

Сначала я подумал, что это было слишком сложно. Затем я понял, что это единственное решение, которое касается поиска недостающих переводов при наличии нескольких «иностранных» языков. Добавьте несколько строк с LanguageNo = 3, чтобы увидеть это. – Fruitbat

+0

Я добавил язык 3 к демо, который по умолчанию закомментирован, из-за того, что ОП не предоставил его. Да, это решение работает для самостоятельного количества языков.Я уверен, что отмеченный ответ не является решением. – Ionic

1
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 
1
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 
+1

Это возвращает все с помощью LanguageNo <> 1. – Fruitbat

+0

См. Move t1.LanguageNo = 1, где – Paparazzi

1

Вы также можете использовать SUM с OVER() вот так.

Запрос

;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 
+0

Да, но будьте осторожны, что это будет работать только для двух языков. Его нужно адаптировать, если у вас больше языков со временем :) – Ionic

Смежные вопросы