내 시나리오는 다음과 같습니다.
나는 내 프로젝트를 위해 지역화 작업을하고 있으며 일반적으로 C # 코드 에서이 작업을 수행하려고하지만 SQL을 조금 강화하려고하기 때문에 SQL 에서이 작업을 조금 더하고 싶습니다.
환경 : SQL Server 2014 Standard, C # (. NET 4.5.1)
참고 : 프로그래밍 언어 자체는 관련이 없어야합니다. 완전성을 위해 포함시켜야합니다.
그래서 나는 내가 원하는 것을 달성했지만 원하는 정도까지 달성하지 못했습니다. JOIN
기본 SQL을 제외한 모든 SQL을 수행 한 이후로 적어도 1 년 이 걸렸습니다 JOIN
. 이는 매우 복잡 합니다.
다음은 데이터베이스의 관련 테이블에 대한 다이어그램입니다. (더 많은 것이 있지만이 부분에는 필요하지 않습니다.)
이미지에 설명 된 모든 관계는 데이터베이스에서 완료됩니다. PK
그리고 FK
제한 조건이 모두 설정 및 작동됩니다. 설명 된 열이 없습니다 null
. 모든 테이블에는 스키마가 dbo
있습니다.
이제, 내가 원하는 것을 거의 수행 하는 쿼리가 있습니다 . 즉, 모든 ID SupportCategories
와 모든 ID가 주어지면 다음 Languages
중 하나를 반환합니다.
해당 문자열에 대한 해당 언어 (IE 용 오른쪽 적절한 번역이있는 경우 StringKeyId
-> StringKeys.Id
존재하고있는 LanguageStringTranslations
StringKeyId
, LanguageId
그리고 StringTranslationId
조합은 다음로드, 존재 StringTranslations.Text
그것에 대해 StringTranslationId
.
는 IF LanguageStringTranslations
StringKeyId
, LanguageId
및 StringTranslationId
조합 않았다 NOT 존재, 다음은로드 StringKeys.Name
값입니다. 는 Languages.Id
주어진됩니다 integer
.
엉망인 내 쿼리는 다음과 같습니다.
SELECT CASE WHEN T.x IS NOT NULL THEN T.x ELSE (SELECT
CASE WHEN dbo.StringTranslations.Text IS NULL THEN dbo.StringKeys.Name ELSE dbo.StringTranslations.Text END AS Result
FROM dbo.SupportCategories
INNER JOIN dbo.StringKeys
ON dbo.SupportCategories.StringKeyId = dbo.StringKeys.Id
INNER JOIN dbo.LanguageStringTranslations
ON dbo.StringKeys.Id = dbo.LanguageStringTranslations.StringKeyId
INNER JOIN dbo.StringTranslations
ON dbo.StringTranslations.Id = dbo.LanguageStringTranslations.StringTranslationId
WHERE dbo.LanguageStringTranslations.LanguageId = 38 AND dbo.SupportCategories.Id = 0) END AS Result FROM (SELECT (SELECT
CASE WHEN dbo.StringTranslations.Text IS NULL THEN dbo.StringKeys.Name ELSE dbo.StringTranslations.Text END AS Result
FROM dbo.SupportCategories
INNER JOIN dbo.StringKeys
ON dbo.SupportCategories.StringKeyId = dbo.StringKeys.Id
INNER JOIN dbo.LanguageStringTranslations
ON dbo.StringKeys.Id = dbo.LanguageStringTranslations.StringKeyId
INNER JOIN dbo.StringTranslations
ON dbo.StringTranslations.Id = dbo.LanguageStringTranslations.StringTranslationId
WHERE dbo.LanguageStringTranslations.LanguageId = 5 AND dbo.SupportCategories.Id = 0) AS x) AS T
문제는 나에게 제공 할 수 없다는 것이다 ALL 의 SupportCategories
및 각각 StringTranslations.Text
존재하는 경우, 또는 그들의 StringKeys.Name
존재하지 않은 경우. 그들 중 하나를 제공하는 데 완벽하지만 전혀 아닙니다. 기본적으로 언어에 특정 키에 대한 번역이없는 경우 기본적으로 번역 된 언어를 사용 StringKeys.Name
하는 것이 StringKeys.DefaultLanguageId
좋습니다. (적어도 그렇게하지는 않지만 대신에 대한 번역을로드 StringKeys.DefaultLanguageId
하면 나머지 쿼리에 올바른 방향을 가리키면 직접 할 수 있습니다.)
나는 이것에 많은 시간을 보냈으며, C #으로 작성 해야하는지 (일반적으로하는 것처럼) 지금까지 수행 될 것임을 알고 있습니다. SQL 에서이 작업을 수행하고 싶습니다. 좋아하는 출력을 얻는 데 문제가 있습니다.
유일한 경고는 적용된 실제 쿼리 수를 제한하고 싶습니다. 모든 열은 색인화되어 있으며 지금은 열이 마음에 들며 실제 스트레스 테스트가 없으면 더 이상 색인을 작성할 수 없습니다.
편집 : 또 다른 메모, 데이터베이스를 가능한 한 표준화 된 상태로 유지하려고하므로 피할 수 있다면 복제하지 않으려 고합니다.
데이터 예
출처
dbo.Support 카테고리 (전체) :
Id StringKeyId
0 0
1 1
2 2
dbo. 언어 (185 개 레코드, 예를 들어 2 개만 표시) :
Id Abbreviation Family Name Native
38 en Indo-European English English
48 fr Indo-European French français, langue française
dbo.LanguagesString 번역 (전체) :
StringKeyId LanguageId StringTranslationId
0 38 0
1 38 1
2 38 2
3 38 3
4 38 4
5 38 5
6 38 6
7 38 7
1 48 8 -- added as example
dbo.StringKeys (전체) :
Id Name DefaultLanguageId
0 Billing 38
1 API 38
2 Sales 38
3 Open 38
4 Waiting for Customer 38
5 Waiting for Support 38
6 Work in Progress 38
7 Completed 38
dbo.String 번역 (전체) :
Id Text
0 Billing
1 API
2 Sales
3 Open
4 Waiting for Customer
5 Waiting for Support
6 Work in Progress
7 Completed
8 Les APIs -- added as example
전류 출력
아래의 정확한 쿼리가 주어지면 다음과 같이 출력됩니다.
Result
Billing
원하는 출력
이상적으로, 나는 특정을 생략 할 수 있도록하고 싶습니다 SupportCategories.Id
그래서 (언어 (38)에 관계없이 것처럼, 그들 모두를 얻을 English
사용, 48 French
, 또는 어떤 순간에 다른 언어) :
Id Result
0 Billing
1 API
2 Sales
추가 예
French
(Ie add 1 48 8
to LanguageStringTranslations
)에 대한 현지화를 추가 하면 출력이 다음으로 변경됩니다 (참고 :이 예제는 분명히 현지화 된 문자열을 StringTranslations
)에 추가합니다 (프랑스어 예제로 업데이트).
Result
Les APIs
추가 원하는 출력
위의 예에서 다음 출력이 필요합니다 (프랑스어 예로 업데이트 됨).
Id Result
0 Billing
1 Les APIs
2 Sales
(예, 기술적으로 일관성 관점에서 잘못된 점을 알고 있지만 상황에서 바람직 할 것입니다.)
편집하다:
작은 업데이트, 나는 dbo.Languages
테이블 의 구조를 변경하고 테이블에서 Id (int)
열을 삭제하고 Abbreviation
(이 이름은로 바뀌고 Id
모든 상대 외래 키 및 관계가 업데이트 됨)로 바꿉니다. 기술적 인 관점에서 볼 때 이것은 표가 처음에는 고유 한 ISO 639-1 코드로 제한되어 있기 때문에 제 생각에 더 적합한 설정입니다.
Tl; dr
그래서 다음 질문은, 어떻게 반환이 쿼리를 수정할 수 있는 모든 의를 SupportCategories
다음 중 하나를 반환 StringTranslations.Text
그것을 위해 StringKeys.Id
, Languages.Id
조합, 또는StringKeys.Name
는 않은 경우 NOT 존재 하는가?
내 생각은 현재 쿼리를 다른 하위 쿼리로 다른 임시 유형으로 캐스팅 하고이 쿼리를 또 다른 SELECT
문으로 래핑 하고 원하는 두 필드 ( SupportCategories.Id
및 Result
)를 선택할 수 있다는 것 입니다.
아무것도 찾지 못하면 일반적으로 사용하는 표준 방법을 사용하여 SupportCategories
C # 프로젝트에 모든 것을로드 한 다음 수동으로 위의 쿼리를 각각 실행합니다 SupportCategories.Id
.
모든 제안 / 의견 / 비평에 감사드립니다.
또한 터무니없이 길어서 죄송합니다. 모호성을 원하지 않습니다. 나는 종종 StackOverflow에 있고 물질이 부족한 질문을 보았습니다. 여기서 실수를하고 싶지 않았습니다.