[英]Sql Server select query for a special usage
我有以下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
我的语言表
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,但可以对其进行修改)?
非常感谢您的任何想法。
最好的问候马克
好吧,首先,您应该有一个与语言无关的所有文档表,然后有一个语言表(我建议对每种语言使用iso值:这是非常全面的,因为klingon也有一个值),然后您需要多对多表(实际上是两个一对多关系的组合),每个表应具有聚簇索引,主键和外键,并涵盖潜在查询的索引。 如果您对这些条款不熟悉,则google和http://www.w3schools.com/sql/都是您的朋友。 在具有这些约束条件的情况下构造的解决方案将完全影响实际(SQL)数据库的功能
您需要添加一列,以指定类似文档的文档类型。 所以我的情况是DOC_TYPE_ID
现在使用以下查询仅发送LANGUAGE_ID,即(1、2、3)
十进制@LANGUAGE_ID INT
SET @LANGUAGE_ID = 1; (将值1更改为德语,将3更改为法语,将2更改为英语)
带有T(ID,DOC_TYPE_ID,TITLE,LANGUAGE_ID,DOCUMENT_RECORD_COUNT)的AS(
从[文档] d中选择d.ID,d.DOC_TYPE_ID,d.TITLE,d.LANGUAGE_ID,DENSE_RANK()超过(按d.DOC_TYPE_ID顺序按d.LANGUAGE_ID DESC顺序分配)
1 =(@LANGUAGE_ID = 3时的情况,然后d.LANGUAGE_ID IN(1,3)然后1的情况,然后@LANGUAGE_ID = 2然后d.LANGUAGE_ID IN(1,2)时的情况,然后1否则0结束的情况d.LANGUAGE_ID = @LANGUAGE_ID THEN 1 ELSE 0 END)
)SELECT ID,DOC_TYPE_ID,TITLE,LANGUAGE_ID,DOCUMENT_RECORD_COUNT个
从T WHERE DOCUMENT_RECORD_COUNT = 1 ORDER BY DOC_TYPE_ID
我认为您应该重组文档表,使其仅包含独立于语言的数据(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;
编辑
为此,您需要在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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.