我有以下SQL Server表:
MyItemsTable(ID和LanguageId是guid的,但我在这里使用int来更容易解释)
Id | Title | LanguageId
1 | My German Document 1 | 1
2 | My German Document 2 | 1
3 | My English Document 1 | 2
4 | My French Document 1 | 3
MyLanguagesTable
LanugageId | Code
1 | de-DE
2 | en-US
3 | fr-FR
MyItemsTable显示有一个文档(文档1)可用于所有语言,一个文档(Document2)仅提供德语版本。
我现在需要的是一个提供所有法国文件的查询,如果没有法文文件,那么请给我德语例如。
法语的结果应如下所示:
My French Document 1
My German Document 2
德语的结果应如下所示:
My German Document 1
My German Document 2
我认为有三件事需要解决:
有没有想法如何以简单的方式构建这样的东西?如何为简单快速的解决方案构建数据库表(给出MyItemsTable和MyLanguagesTable但可以修改)?
非常感谢您的任何想法。
祝你好运 马克
答案 0 :(得分:0)
首先你应该拥有一个独立于语言的所有文档的表,然后有一个语言表(我建议使用每种语言的iso值:这是非常全面的,因为klingon还有一个值)然后你需要一个多对多的表(实际上是两个一对多关系的组合),每个表应该有聚簇索引,主键和外键,以及覆盖潜在查询的索引。如果这些条款中的任何一项对您来说都是新的,那么谷歌就是您的朋友http://www.w3schools.com/sql/。使用这些约束构造时的解决方案将完全实现realtional(SQL)数据库的强大功能
答案 1 :(得分:0)
您需要添加一个列,指定类似文档的doc类型。 所以在我的情况下它的DOC_TYPE_ID
现在使用以下查询来发送LANGUAGE_ID,即(1,2,3)
DECLARE @LANGUAGE_ID INT
SET @LANGUAGE_ID = 1; (德语改为1,法语改为3,2 对于英语)
WITH T(ID,DOC_TYPE_ID,TITLE,LANGUAGE_ID,DOCUMENT_RECORD_COUNT) AS(
SELECT d.ID,d.DOC_TYPE_ID,d.TITLE,d.LANGUAGE_ID,DENSE_RANK()OVER (由d.LANGUAGE_ID DESC划分d.DOC_TYPE_ID订购)AS DOCUMENT_RECORD_COUNT来自[文件] d
在哪里1 =(当@LANGUAGE_ID = 3时为例当d.LANGUAGE_ID为 (1,3)那么1 0结束 当@LANGUAGE_ID = 2时那么d.LANGUAGE_ID在(1,2)那么1节0结束 当d.LANGUAGE_ID = @LANGUAGE_ID那么1 ELSE 0 END )
)SELECT ID,DOC_TYPE_ID,TITLE,LANGUAGE_ID,DOCUMENT_RECORD_COUNT
FROM T WHERE DOCUMENT_RECORD_COUNT = 1 ORDER BY DOC_TYPE_ID
答案 2 :(得分:0)
我认为你应该重新构建你的文档表,只包含语言独立数据(DocumentID,创建日期,创建用户文档类型等),
然后有另一个表包含每种语言的数据(DocumentVersion),其中documentid和languageID构成主键:
DocumentID | LanguageID | Title
但是,由于您的语言代码是每种语言的唯一值,我会将其作为自然主键(或者您可以使用sys.syslanguages)。这是我将用于此问题的数据结构:
CREATE TABLE Document
( DocumentID INT IDENTITY(1, 1) NOT NULL CONSTRAINT PK_Document_DocumentID PRIMARY KEY,
DefaultTitle VARCHAR(100) NOT NULL,
CreatedDate DATETIME NOT NULL
);
CREATE TABLE dbo.[Language]
( LanguageCode CHAR(5) NOT NULL CONSTRAINT PK_Lanaguage_LanguageCode PRIMARY KEY,
Name VARCHAR(50) NOT NULL,
Alias VARCHAR(50) NOT NULL
);
CREATE TABLE dbo.DocumentVersion
( DocumentFK INT NOT NULL,
LanguageCode CHAR(5) NOT NULL,
Title VARCHAR(50) NOT NULL
CONSTRAINT PK_DocumentVersion PRIMARY KEY (DocumentFK, LanguageCode)
CONSTRAINT FK_DocumentVersion_LanguageCode FOREIGN KEY (LanguageCode) REFERENCES dbo.[Language] (LanguageCode),
CONSTRAINT FK_DocumentVersion_DocumentID FOREIGN KEY (DocumentFK) REFERENCES dbo.Document (DocumentID)
);
INSERT Document (DefaultTitle, CreatedDate)
VALUES
('Document 1', CURRENT_TIMESTAMP),
('Document 2', CURRENT_TIMESTAMP);
INSERT dbo.[Language] (LanguageCode, Name, Alias)
VALUES
('de-DE', 'Deutsch', 'German'),
('en-US', 'US English', 'English'),
('fr-FR', 'Français', 'French');
INSERT dbo.DocumentVersion (DocumentFK, LanguageCode, Title)
VALUES
(1, 'de-DE', 'My German Document 1'),
(2, 'de-DE', 'My German Document 2'),
(1, 'en-US', 'My English Document 1'),
(1, 'fr-FR', 'My French Document 1')
为了以您所说的方式获取文档,您需要一个自定义案例陈述来获得正确的顺序。因此,使用上面的示例,您可以使用
DECLARE @PrimaryLanguage CHAR(5) = 'fr-FR',
@DefaultLanguage CHAR(5) = 'de-DE';
WITH RankedDocument AS
( SELECT DocumentFK,
LanguageCode,
Title,
SortOrder = CASE WHEN LanguageCode = @PrimaryLanguage THEN 1
WHEN LanguageCode = @DefaultLanguage THEN 2
-- MORE SORTING CRITERIA IF REQURED
ELSE 10
END
FROM DocumentVersion
), Docs AS
( SELECT d.DocumentID,
rd.Title,
d.CreatedDate,
rn = ROW_NUMBER() OVER(PARTITION BY d.DocumentID ORDER BY rd.SortOrder)
FROM Document d
INNER JOIN RankedDocument rd
ON d.DocumentID = rd.DocumentFK
)
SELECT DocumentID, Title, CreatedDate
FROM Docs
WHERE rn = 1;
<强> Example with French Documents 强>
<强> Example with German Documents 强>
修改强>
要使用当前结构执行此操作,您需要向MyItemsTable
添加一个字段,这应该可能是新表的外键,为了演示,我刚刚使用了LinkField
:
DECLARE @PrimaryLanguage INT = 1,
@DefaultLanguage INT = 1;
WITH RankedItem AS
( SELECT ID,
Title,
LanguageId,
rn = ROW_NUMBER() OVER(PARTITION BY LinkField ORDER BY CASE LanguageId
WHEN @PrimaryLanguage THEN 1
WHEN @DefaultLanguage THEN 2
ELSE 10
END)
FROM MyItemsTable
)
SELECT ID, Title, LanguageID
FROM RankedItem
WHERE rn = 1;
<强> Demo on SQL Fiddle 强>