我在SQL Server 2008R2中有以下四个表:
DECLARE @ParentGroup TABLE (ParentGroup_ID INT, ParentGroup_Name VARCHAR(100));
DECLARE @ChildGroup TABLE (ChildGroup_id INT, ChildGroup_name VARCHAR(100), ParentGroup_id INT);
DECLARE @Entity TABLE ([Entity_id] INT, [Entity_name] VARCHAR(100));
DECLARE @ChildGroupEntity TABLE (ChildGroupEntity_id INT, ChildGroup_id INT, [Entity_ID] INT);
INSERT INTO @parentGroup VALUES (1, 'England'), (2, 'USA');
INSERT INTO @ChildGroup VALUES (10, 'Sussex', 1), (11, 'Essex', 1), (12, 'Middlesex', 1);
INSERT INTO @entity VALUES (100, 'Entity0'),(101, 'Entity1'),(102, 'Entity2'),(103, 'Entity3'),(104, 'Entity4'),(105, 'Entity5'),(106, 'Entity6');
INSERT INTO @ChildGroupEntity VALUES (1000, 10, 100), (1001, 10, 101), (1002, 10, 102), (1003, 11, 103), (1004, 11, 104), (1005, 12, 100), (1006, 12, 105), (1007, 12, 106);
/*
SELECT * FROM @parentGroup
SELECT * FROM @ChildGroup
SELECT * FROm @entity
SELECT * FROM @ChildGroupEntity
*/
表格之间的关系如下:
SELECT ParentGroup_Name, ChildGroup_name, [Entity_name], 0 [ChildGroupSequence], 0 [EntitySequence]
FROM @ChildGroupEntity cge
INNER JOIN @ChildGroup cg ON cg.ChildGroup_id=cge.ChildGroup_id
INNER JOIN @parentGroup pg ON pg.parentGroup_id=cg.parentGroup_id
INNER JOIN @entity e ON e.[entity_id]=cge.[Entity_ID]
ORDER BY ParentGroup_Name, ChildGroup_name, [Entity_name]
以上查询的输出为:
-------------------------------------------------------------------------------
ParentGroup_Name|ChildGroup_name|Entity_name|ChildGroupSequence|EntitySequence|
-------------------------------------------------------------------------------
England |Essex |Entity3 |0 |0 |
England |Essex |Entity4 |0 |0 |
England |Middlesex |Entity0 |0 |0 |
England |Middlesex |Entity5 |0 |0 |
England |Middlesex |Entity6 |0 |0 |
England |Sussex |Entity0 |0 |0 |
England |Sussex |Entity1 |0 |0 |
England |Sussex |Entity2 |0 |0 |
-------------------------------------------------------------------------------
现在,我想找出子组和与父组1的子组关联的所有实体。另外,我想计算[ChildGroupSequence],[EntitySequence]和下面的逻辑:
因此,输出应采用以下格式:
-------------------------------------------------------------------------------
ParentGroup_Name|ChildGroup_name|Entity_name|ChildGroupSequence|EntitySequence|
-------------------------------------------------------------------------------
England |Essex |Entity3 |1000 |100 |
England |Essex |Entity4 |1000 |101 |
England |Middlesex |Entity0 |1100 |100 |
England |Middlesex |Entity5 |1100 |101 |
England |Middlesex |Entity6 |1100 |102 |
England |Sussex |Entity0 |1200 |100 |
England |Sussex |Entity1 |1200 |101 |
England |Sussex |Entity2 |1200 |102 |
-------------------------------------------------------------------------------
我可以通过在应用程序层(.Net程序)中读取值来轻松完成此操作,但希望通过尝试这样的一些小事来学习SQL服务器。任何人都可以帮我写这个SQL查询吗?
非常感谢任何帮助。提前谢谢。
编辑: 我的示例数据似乎没有正确反映第一个规则,规则规定ChildGroupSequence应该增加100并且示例输出增加1.第二个查询反映增量为100. @jpw:非常感谢你指点这个。
答案 0 :(得分:1)
我相信这可以使用partitioning和ranking这样的函数完成:
SELECT ParentGroup_Name, ChildGroup_name, [Entity_name],
999 + DENSE_RANK() OVER(PARTITION BY ParentGroup_Name ORDER BY ChildGroup_name) AS [ChildGroupSequence],
99 + ROW_NUMBER() OVER(PARTITION BY ParentGroup_Name, ChildGroup_name ORDER BY ChildGroup_name, Entity_name) AS [EntitySequence]
FROM @ChildGroupEntity cge
INNER JOIN @ChildGroup cg ON cg.ChildGroup_id=cge.ChildGroup_id
INNER JOIN @parentGroup pg ON pg.parentGroup_id=cg.parentGroup_id
INNER JOIN @entity e ON e.[entity_id]=cge.[Entity_ID]
ORDER BY ParentGroup_Name, ChildGroup_name, [Entity_name]
此查询生成您描述的示例输出。您的示例数据似乎没有正确反映第一个规则,但规则规定ChildGroupSequence应增加100并且示例输出增加1.第二个查询将增量反映100:
SELECT ParentGroup_Name, ChildGroup_name, [Entity_name],
900 + 100 * DENSE_RANK() OVER(PARTITION BY ParentGroup_Name ORDER BY ChildGroup_name) AS [ChildGroupSequence],
99 + ROW_NUMBER() OVER(PARTITION BY ParentGroup_Name, ChildGroup_name ORDER BY ChildGroup_name, Entity_name) AS [EntitySequence]
FROM @ChildGroupEntity cge
INNER JOIN @ChildGroup cg ON cg.ChildGroup_id=cge.ChildGroup_id
INNER JOIN @parentGroup pg ON pg.parentGroup_id=cg.parentGroup_id
INNER JOIN @entity e ON e.[entity_id]=cge.[Entity_ID]
ORDER BY ParentGroup_Name, ChildGroup_name, [Entity_name]
有关这两个查询的示例,请参阅此sample SQL Fiddle。
也许查询应该按ID而不是Name进行分区,如果是这样的话,Sussex将会出现在Essex之前,因为它的ID较低,查询将是:
SELECT ParentGroup_Name, ChildGroup_name, [Entity_name],
900 + 100 * DENSE_RANK() OVER(PARTITION BY pg.ParentGroup_ID ORDER BY cg.ChildGroup_ID) AS [ChildGroupSequence],
99 + ROW_NUMBER() OVER(PARTITION BY pg.ParentGroup_ID, cg.ChildGroup_ID ORDER BY cg.ChildGroup_ID, cge.Entity_ID) AS [EntitySequence]
FROM @ChildGroupEntity cge
INNER JOIN @ChildGroup cg ON cg.ChildGroup_id=cge.ChildGroup_id
INNER JOIN @parentGroup pg ON pg.parentGroup_id=cg.parentGroup_id
INNER JOIN @entity e ON e.[entity_id]=cge.[Entity_ID]
ORDER BY pg.ParentGroup_ID, cg.ChildGroup_ID, [Entity_name]
答案 1 :(得分:1)
SELECT ParentGroup_Name,
ChildGroup_name,
[Entity_name],
LU.R [ChildGroupSequence],
99 + ROW_NUMBER() OVER (PARTITION BY LU.ParentGroup_id,LU.ChildGroup_id ORDER BY ChildGroup_name) [EntitySequence]
FROM @ChildGroupEntity cge
JOIN (
SELECT cg.ChildGroup_id,
cg.ChildGroup_name,
pg.ParentGroup_id,
pg.ParentGroup_Name,
999 + (ROW_NUMBER() OVER (ORDER BY cg.ChildGroup_id)) [R]
FROM @ChildGroup cg
JOIN @parentGroup pg On pg.ParentGroup_ID = cg.ParentGroup_ID) LU
ON cge.ChildGroup_id = LU.ChildGroup_id
INNER JOIN @entity e ON e.[entity_id]=cge.[Entity_ID]
ORDER BY LU.ParentGroup_Name, LU.ChildGroup_name, e.[Entity_name]
结果:
答案 2 :(得分:1)
您可以使用ranking functions
解决此问题SELECT ParentGroup_Name, ChildGroup_name, [Entity_name],
899 + DENSE_RANK() OVER(PARTITION BY ParentGroup_Name ORDER BY ChildGroup_name) +
100 * DENSE_RANK() OVER(ORDER BY ParentGroup_Name ASC) AS ChildGroupSequence,
99 + ROW_NUMBER() OVER(PARTITION BY ParentGroup_Name, ChildGroup_name ORDER BY [Entity_name]) AS [EntitySequence]
FROM @ChildGroupEntity cge
INNER JOIN @ChildGroup cg ON cg.ChildGroup_id=cge.ChildGroup_id
INNER JOIN @parentGroup pg ON pg.parentGroup_id=cg.parentGroup_id
INNER JOIN @entity e ON e.[entity_id]=cge.[Entity_ID]
ORDER BY ParentGroup_Name, ChildGroup_name, [Entity_name]
您可以在此处找到SQL Fiddle