Ort*_*iga 11 sql sql-server sql-server-2014
关于相关领域部分的简要说明:
类别由四个数据组成:
因此,Male Adult Black Rooster
形成一个类别.可能不存在某些组合,例如强大的螨黑带.
一名运动员与同一类别的运动员作战,如果他分类,他会与不同重量级别的运动员作战(但性别,年龄和腰带相同).
去建模.我有一个Category
表,已经填充了域中存在的所有组合.
CREATE TABLE Category (
[Id] [int] IDENTITY(1,1) NOT NULL,
[AgeDivision_Id] [int] NULL,
[Gender] [int] NULL,
[BeltColor] [int] NULL,
[WeightDivision] [int] NULL
)
Run Code Online (Sandbox Code Playgroud)
A CategorySet
和a CategorySet_Category
,形成多对多的关系Category
.
CREATE TABLE CategorySet (
[Id] [int] IDENTITY(1,1) NOT NULL,
[Championship_Id] [int] NOT NULL,
)
CREATE TABLE CategorySet_Category (
[CategorySet_Id] [int] NOT NULL,
[Category_Id] [int] NOT NULL
)
Run Code Online (Sandbox Code Playgroud)
给定以下结果集:
| Options_Id | Championship_Id | AgeDivision_Id | BeltColor | Gender | WeightDivision |
|------------|-----------------|----------------|-----------|--------|----------------|
1. | 2963 | 422 | 15 | 7 | 0 | 0 |
2. | 2963 | 422 | 15 | 7 | 0 | 1 |
3. | 2963 | 422 | 15 | 7 | 0 | 2 |
4. | 2963 | 422 | 15 | 7 | 0 | 3 |
5. | 2964 | 422 | 15 | 8 | 0 | 0 |
6. | 2964 | 422 | 15 | 8 | 0 | 1 |
7. | 2964 | 422 | 15 | 8 | 0 | 2 |
8. | 2964 | 422 | 15 | 8 | 0 | 3 |
Run Code Online (Sandbox Code Playgroud)
因为运动员可以对抗两个分类集,我需要CategorySet
并CategorySet_Category
以两种不同的方式填充(可以是两个查询):
其中Category_Set
的每一行,有一个CategorySet_Category
指向相应Category
.
一个Category_Set
是集团在一个所有WeightDivisions CategorySet
在同一AgeDivision_Id,BeltColor,性别.在此示例中,仅有所BeltColor
不同.
所以最终的结果总共有10 CategorySet
行:
| Id | Championship_Id |
|----|-----------------|
| 1 | 422 |
| 2 | 422 |
| 3 | 422 |
| 4 | 422 |
| 5 | 422 |
| 6 | 422 |
| 7 | 422 |
| 8 | 422 |
| 9 | 422 | /* groups different Weight Division for BeltColor 7 */
| 10 | 422 | /* groups different Weight Division for BeltColor 8 */
Run Code Online (Sandbox Code Playgroud)
而且CategorySet_Category
将有16行:
| CategorySet_Id | Category_Id |
|----------------|-------------|
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
| 7 | 7 |
| 8 | 8 |
| 9 | 1 | /* groups different Weight Division for BeltColor 7 */
| 9 | 2 | /* groups different Weight Division for BeltColor 7 */
| 9 | 3 | /* groups different Weight Division for BeltColor 7 */
| 9 | 4 | /* groups different Weight Division for BeltColor 7 */
| 10 | 5 | /* groups different Weight Division for BeltColor 8 */
| 10 | 6 | /* groups different Weight Division for BeltColor 8 */
| 10 | 7 | /* groups different Weight Division for BeltColor 8 */
| 10 | 8 | /* groups different Weight Division for BeltColor 8 */
Run Code Online (Sandbox Code Playgroud)
我不知道如何插入CategorySet
,抓取它生成的Id,然后用它插入CategorySet_Category
我希望我的意图明确.
编辑1:我在Jacek的回答中评论说这只会运行一次,但这是错误的.它每周会运行几次.我可以选择从C#或存储过程作为SQL命令运行.表现并不重要.
编辑2: Jacek建议使用SCOPE_IDENTITY
返回Id.问题是,SCOPE_IDENTITY
只返回最后插入的Id,并且我插入了多行CategorySet
.
编辑3:回答@FutbolFan谁询问如何检索FakeResultSet.
这是一张桌子CategoriesOption
(Id,Price_Id,MaxAthletesByTeam)
和表格CategoriesOptionBeltColor
,CategoriesOptionAgeDivision
,CategoriesOptionWeightDivison
,CategoriesOptionGender
.这四个表基本相同(Id,CategoriesOption_Id,Value).
查询看起来像这样:
SELECT * FROM CategoriesOption co
LEFT JOIN CategoriesOptionAgeDivision ON
CategoriesOptionAgeDivision.CategoriesOption_Id = co.Id
LEFT JOIN CategoriesOptionBeltColor ON
CategoriesOptionBeltColor.CategoriesOption_Id = co.Id
LEFT JOIN CategoriesOptionGender ON
CategoriesOptionGender.CategoriesOption_Id = co.Id
LEFT JOIN CategoriesOptionWeightDivision ON
CategoriesOptionWeightDivision.CategoriesOption_Id = co.Id
Run Code Online (Sandbox Code Playgroud)
此处描述的解决方案将在多用户环境中以及目标表CategorySet
和CategorySet_Category
不为空时正常工作。我使用了SQL Fiddle中的架构和示例数据。
第一部分很简单
(ab)MERGE
与OUTPUT
子句一起使用。
MERGE
可以INSERT
和UPDATE
行DELETE
。在我们的例子中,我们只需要INSERT
. 1=0
始终为假,因此该NOT MATCHED BY TARGET
部分始终被执行。一般来说,可能还有其他分支,请参阅文档。WHEN MATCHED
通常用于UPDATE
; WHEN NOT MATCHED BY SOURCE
通常用于DELETE
,但我们这里不需要它们。
这种复杂的形式MERGE
相当于 simple INSERT
,但与 simple 不同的是,INSERT
它的OUTPUT
子句允许引用我们需要的列。
MERGE INTO CategorySet
USING
(
SELECT
FakeResultSet.Championship_Id
,FakeResultSet.Price_Id
,FakeResultSet.MaxAthletesByTeam
,Category.Id AS Category_Id
FROM
FakeResultSet
INNER JOIN Category ON
Category.AgeDivision_Id = FakeResultSet.AgeDivision_Id AND
Category.Gender = FakeResultSet.Gender AND
Category.BeltColor = FakeResultSet.BeltColor AND
Category.WeightDivision = FakeResultSet.WeightDivision
) AS Src
ON 1 = 0
WHEN NOT MATCHED BY TARGET THEN
INSERT
(Championship_Id
,Price_Id
,MaxAthletesByTeam)
VALUES
(Src.Championship_Id
,Src.Price_Id
,Src.MaxAthletesByTeam)
OUTPUT inserted.id AS CategorySet_Id, Src.Category_Id
INTO CategorySet_Category (CategorySet_Id, Category_Id)
;
Run Code Online (Sandbox Code Playgroud)
FakeResultSet
与 相连接Category
以获取Category.id
的每一行FakeResultSet
。假设Category
具有 的唯一组合AgeDivision_Id, Gender, BeltColor, WeightDivision
。
在OUTPUT
子句中,我们需要源表和目标表中的列。OUTPUT
simple 语句中的子句没有INSERT
提供它们,所以我们MERGE
在这里使用提供的。
上面的查询MERGE
将插入 8 行CategorySet
,并使用生成的 ID 插入 8 行CategorySet_Category
。
第二部分
需要临时表。我将使用表变量来存储生成的 ID。
DECLARE @T TABLE (
CategorySet_Id int
,AgeDivision_Id int
,Gender int
,BeltColor int);
Run Code Online (Sandbox Code Playgroud)
我们需要记住所产生的以及导致它CategorySet_Id
的组合。AgeDivision_Id, Gender, BeltColor
MERGE INTO CategorySet
USING
(
SELECT
FakeResultSet.Championship_Id
,FakeResultSet.Price_Id
,FakeResultSet.MaxAthletesByTeam
,FakeResultSet.AgeDivision_Id
,FakeResultSet.Gender
,FakeResultSet.BeltColor
FROM
FakeResultSet
GROUP BY
FakeResultSet.Championship_Id
,FakeResultSet.Price_Id
,FakeResultSet.MaxAthletesByTeam
,FakeResultSet.AgeDivision_Id
,FakeResultSet.Gender
,FakeResultSet.BeltColor
) AS Src
ON 1 = 0
WHEN NOT MATCHED BY TARGET THEN
INSERT
(Championship_Id
,Price_Id
,MaxAthletesByTeam)
VALUES
(Src.Championship_Id
,Src.Price_Id
,Src.MaxAthletesByTeam)
OUTPUT
inserted.id AS CategorySet_Id
,Src.AgeDivision_Id
,Src.Gender
,Src.BeltColor
INTO @T(CategorySet_Id, AgeDivision_Id, Gender, BeltColor)
;
Run Code Online (Sandbox Code Playgroud)
上面将根据需要MERGE
进行分组,并将 2 行插入到 中,并将 2 行插入到 中。FakeResultSet
CategorySet
@T
然后加入@T
得到:Category
Category.IDs
INSERT INTO CategorySet_Category (CategorySet_Id, Category_Id)
SELECT
TT.CategorySet_Id
,Category.Id AS Category_Id
FROM
@T AS TT
INNER JOIN Category ON
Category.AgeDivision_Id = TT.AgeDivision_Id AND
Category.Gender = TT.Gender AND
Category.BeltColor = TT.BeltColor
;
Run Code Online (Sandbox Code Playgroud)
这将插入 8 行到CategorySet_Category
.
归档时间: |
|
查看次数: |
1977 次 |
最近记录: |