en en ko ko ko ja en en zh en pt ko ja ko ko ko zh ko ko ko ko ko ko ko ko en ko ko ko ko ko ko ko id ko en ko en fr en ko en ko ko en ko ko en ko ko ca ko ko en ko ko ko sl ko ko ko ko ko nl ko en ko ko nl ko en ko ko ko ko en ko en nl ko ko ko ko ko zh en en en en pt fr en en kn en sv fr en en en en en es fr en en en fr ja en en en en en en en en en fi en hu pt hbs_lat ru en en en en pl ko ko ko ko ko ko ko zh en en pt en en en uz en en fr eo sv en en en es en en en en en en ja en it hu ja eo en de en ko ko en en
모든 레코드를 선택하고 결합이 존재하면 테이블 A와 결합하고, 존재하지 않으면 테이블 B ON dbo.StringTranslations.Id =
나는 내 프로젝트를 위해 지역화 작업을하고 있으며 일반적으로 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중 하나를 반환합니다.
는 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
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
아래의 정확한 쿼리가 주어지면 다음과 같이 출력됩니다.
이상적으로, 나는 특정을 생략 할 수 있도록하고 싶습니다 SupportCategories.Id그래서 (언어 (38)에 관계없이 것처럼, 그들 모두를 얻을 English사용, 48 French, 또는 어떤 순간에 다른 언어) :
Id Result 0 Billing 1 API 2 Sales
French(Ie add 1 48 8to LanguageStringTranslations)에 대한 현지화를 추가 하면 출력이 다음으로 변경됩니다 (참고 :이 예제는 분명히 현지화 된 문자열을 StringTranslations)에 추가합니다 (프랑스어 예제로 업데이트).
위의 예에서 다음 출력이 필요합니다 (프랑스어 예로 업데이트 됨).
Id Result 0 Billing 1 Les APIs 2 Sales
(예, 기술적으로 일관성 관점에서 잘못된 점을 알고 있지만 상황에서 바람직 할 것입니다.)
작은 업데이트, 나는 dbo.Languages테이블 의 구조를 변경하고 테이블에서 Id (int)열을 삭제하고 Abbreviation(이 이름은로 바뀌고 Id모든 상대 외래 키 및 관계가 업데이트 됨)로 바꿉니다. 기술적 인 관점에서 볼 때 이것은 표가 처음에는 고유 한 ISO 639-1 코드로 제한되어 있기 때문에 제 생각에 더 적합한 설정입니다.
그래서 다음 질문은, 어떻게 반환이 쿼리를 수정할 수 있는 모든 의를 SupportCategories다음 중 하나를 반환 StringTranslations.Text그것을 위해 StringKeys.Id, Languages.Id조합, 또는StringKeys.Name 는 않은 경우 NOT 존재 하는가?
내 생각은 현재 쿼리를 다른 하위 쿼리로 다른 임시 유형으로 캐스팅 하고이 쿼리를 또 다른 SELECT문으로 래핑 하고 원하는 두 필드 ( SupportCategories.Id및 Result)를 선택할 수 있다는 것 입니다.
아무것도 찾지 못하면 일반적으로 사용하는 표준 방법을 사용하여 SupportCategoriesC # 프로젝트에 모든 것을로드 한 다음 수동으로 위의 쿼리를 각각 실행합니다 SupportCategories.Id.
모든 제안 / 의견 / 비평에 감사드립니다.
또한 터무니없이 길어서 죄송합니다. 모호성을 원하지 않습니다. 나는 종종 StackOverflow에 있고 물질이 부족한 질문을 보았습니다. 여기서 실수를하고 싶지 않았습니다.
내가 생각해 낸 첫 번째 접근법은 다음과 같습니다.
DECLARE @ChosenLanguage INT = 48; SELECT sc.Id, Result = MAX(COALESCE( CASE WHEN lst.LanguageId = @ChosenLanguage THEN st.Text END, CASE WHEN lst.LanguageId = sk.DefaultLanguageId THEN st.Text END) ) FROM dbo.SupportCategories AS sc INNER JOIN dbo.StringKeys AS sk ON sc.StringKeyId = sk.Id LEFT OUTER JOIN dbo.LanguageStringTranslations AS lst ON sk.Id = lst.StringKeyId AND lst.LanguageId IN (sk.DefaultLanguageId, @ChosenLanguage) LEFT OUTER JOIN dbo.StringTranslations AS st ON st.Id = lst.StringTranslationId --WHERE sc.Id = 1 GROUP BY sc.Id ORDER BY sc.Id;
기본적으로 선택한 언어 와 일치하는 잠재적 문자열을 가져 와서 모든 기본 문자열을 얻은 다음 집계 Id하여 선택한 언어에 대해 우선 순위를 정한 다음 기본값을 폴백으로 사용하십시오.
UNION/ 와 비슷한 작업을 수행 할 수는 EXCEPT있지만 거의 동일한 객체에 대해 여러 번 스캔 할 것으로 생각합니다.
INAaron의 답변에서 및 그룹 을 피하는 대체 솔루션 :
DECLARE @SelectedLanguageId integer = 48; SELECT SC.Id, SC.StringKeyId, Result = CASE -- No localization available WHEN LST.StringTranslationId IS NULL THEN SK.Name ELSE ( -- Localized string SELECT ST.[Text] FROM dbo.StringTranslations AS ST WHERE ST.Id = LST.StringTranslationId ) END FROM dbo.SupportCategories AS SC JOIN dbo.StringKeys AS SK ON SK.Id = SC.StringKeyId LEFT JOIN dbo.LanguageStringTranslations AS LST WITH (FORCESEEK) -- Only for low row count in sample data ON LST.StringKeyId = SK.Id AND LST.LanguageId = @SelectedLanguageId;
언급 한 바와 같이, FORCESEEK힌트는 LanguageStringTranslations제공된 샘플 데이터로 테이블의 카디널리티가 낮기 때문에 가장 효율적인 계획을 얻는 데만 필요합니다 . 행이 많을수록 옵티마이 저는 자연스럽게 인덱스 탐색을 선택합니다.
실행 계획 자체에는 흥미로운 기능이 있습니다.
마지막 외부 조인의 통과 특성은 StringTranslations테이블에 대한 행이 이전에 LanguageStringTranslations테이블 에서 발견 된 경우에만 테이블 찾아보기가 수행됨 을 의미 합니다. 그렇지 않으면이 조인의 내부가 현재 행에 대해 완전히 건너 뜁니다.
CREATE TABLE dbo.Languages ( Id integer NOT NULL, Abbreviation char(2) NOT NULL, Family nvarchar(96) NOT NULL, Name nvarchar(96) NOT NULL, [Native] nvarchar(96) NOT NULL, CONSTRAINT PK_dbo_Languages PRIMARY KEY CLUSTERED (Id) ); CREATE TABLE dbo.StringTranslations ( Id bigint NOT NULL, [Text] nvarchar(128) NOT NULL, CONSTRAINT PK_dbo_StringTranslations PRIMARY KEY CLUSTERED (Id) ); CREATE TABLE dbo.StringKeys ( Id bigint NOT NULL, Name varchar(64) NOT NULL, DefaultLanguageId integer NOT NULL, CONSTRAINT PK_dbo_StringKeys PRIMARY KEY CLUSTERED (Id), CONSTRAINT FK_dbo_StringKeys_DefaultLanguageId FOREIGN KEY (DefaultLanguageId) REFERENCES dbo.Languages (Id) ); CREATE TABLE dbo.SupportCategories ( Id integer NOT NULL, StringKeyId bigint NOT NULL, CONSTRAINT PK_dbo_SupportCategories PRIMARY KEY CLUSTERED (Id), CONSTRAINT FK_dbo_SupportCategories FOREIGN KEY (StringKeyId) REFERENCES dbo.StringKeys (Id) ); CREATE TABLE dbo.LanguageStringTranslations ( StringKeyId bigint NOT NULL, LanguageId integer NOT NULL, StringTranslationId bigint NOT NULL, CONSTRAINT PK_dbo_LanguageStringTranslations PRIMARY KEY CLUSTERED (StringKeyId, LanguageId, StringTranslationId), CONSTRAINT FK_dbo_LanguageStringTranslations_StringKeyId FOREIGN KEY (StringKeyId) REFERENCES dbo.StringKeys (Id), CONSTRAINT FK_dbo_LanguageStringTranslations_LanguageId FOREIGN KEY (LanguageId) REFERENCES dbo.Languages (Id), CONSTRAINT FK_dbo_LanguageStringTranslations_StringTranslationId FOREIGN KEY (StringTranslationId) REFERENCES dbo.StringTranslations (Id) );
INSERT dbo.Languages (Id, Abbreviation, Family, Name, [Native]) VALUES (38, 'en', N'Indo-European', N'English', N'English'), (48, 'fr', N'Indo-European', N'French', N'français, langue française'); INSERT dbo.StringTranslations (Id, [Text]) VALUES (0, N'Billing'), (1, N'API'), (2, N'Sales'), (3, N'Open'), (4, N'Waiting for Customer'), (5, N'Waiting for Support'), (6, N'Work in Progress'), (7, N'Completed'), (8, N'Les APIs'); -- added as example INSERT dbo.StringKeys (Id, Name, DefaultLanguageId) VALUES (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); INSERT dbo.SupportCategories (Id, StringKeyId) VALUES (0, 0), (1, 1), (2, 2); INSERT dbo.LanguageStringTranslations (StringKeyId, LanguageId, StringTranslationId) VALUES (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
이 글은 Sql 카테고리에 분류되었고 sql-server, sql-server-2014, t-sql 태그가 있으며 소장 마님에 의해 2022-09-26에 작성되었습니다.
특정 결말을 가진 파일이없는 디렉토리 찾기 디렉토리를 표시하고
R에서 eCDF와 신속하게 통합 d\hat{F}_n(y) F^nF^n\hat{F}_nggg 그러나 이것은
Emacs에서 ispell의 개인 사전은 어디에 저장됩니까? 곳은 ispell 개인 사전? 문서가 저장되어있다 http://www.gnu.org/software/emacs/manual/html_node/emacs/Spelling.html가
AUC 대신 정규화 된 Gini Score를 평가로 사용하는 이유는 무엇입니까? Safe Driver Prediction 은 Normalized Gini
내 PHP 설치 경로는 어디입니까 centos를 사용하고
Proudly powered by WordPress