Skip to content

Commit 438b05f

Browse files
authored
Query: Lift projections from single result query rather than applying nested (#24715)
This fixes slight regression which was introduced in #24675 We need to lift projections for single result since if there is a split query on it then we need it joined to top level to get proper parent query to clone
1 parent 9fe0d4b commit 438b05f

13 files changed

+120
-166
lines changed

src/EFCore.Relational/Query/SqlExpressions/SelectExpression.Helper.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,26 +128,29 @@ public ProjectionMemberToIndexConvertingExpressionVisitor(
128128

129129
private sealed class ProjectionIndexRemappingExpressionVisitor : ExpressionVisitor
130130
{
131-
private readonly SelectExpression _queryExpression;
131+
private readonly SelectExpression _oldSelectExpression;
132+
private readonly SelectExpression _newSelectExpression;
132133
private readonly int[] _indexMap;
133134

134135
public ProjectionIndexRemappingExpressionVisitor(
135-
SelectExpression queryExpression, int[] indexMap)
136+
SelectExpression oldSelectExpression, SelectExpression newSelectExpression, int[] indexMap)
136137
{
137-
_queryExpression = queryExpression;
138+
_oldSelectExpression = oldSelectExpression;
139+
_newSelectExpression = newSelectExpression;
138140
_indexMap = indexMap;
139141
}
140142

141143
[return: NotNullIfNotNull("expression")]
142144
public override Expression? Visit(Expression? expression)
143145
{
144-
if (expression is ProjectionBindingExpression projectionBindingExpression)
146+
if (expression is ProjectionBindingExpression projectionBindingExpression
147+
&& ReferenceEquals(projectionBindingExpression.QueryExpression, _oldSelectExpression))
145148
{
146149
Check.DebugAssert(projectionBindingExpression.Index != null,
147150
"ProjectionBindingExpression must have index.");
148151

149152
return new ProjectionBindingExpression(
150-
_queryExpression,
153+
_newSelectExpression,
151154
_indexMap[projectionBindingExpression.Index.Value],
152155
projectionBindingExpression.Type);
153156
}
@@ -541,9 +544,9 @@ public SplitCollectionInfo(
541544

542545
private sealed class ClientProjectionRemappingExpressionVisitor : ExpressionVisitor
543546
{
544-
private readonly object[] _clientProjectionIndexMap;
547+
private readonly List<object> _clientProjectionIndexMap;
545548

546-
public ClientProjectionRemappingExpressionVisitor(object[] clientProjectionIndexMap)
549+
public ClientProjectionRemappingExpressionVisitor(List<object> clientProjectionIndexMap)
547550
{
548551
_clientProjectionIndexMap = clientProjectionIndexMap;
549552
}
@@ -562,7 +565,7 @@ public ClientProjectionRemappingExpressionVisitor(object[] clientProjectionIndex
562565

563566
if (value is Expression innerShaper)
564567
{
565-
return innerShaper;
568+
return Visit(innerShaper);
566569
}
567570

568571
throw new InvalidCastException();

src/EFCore.Relational/Query/SqlExpressions/SelectExpression.cs

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -403,20 +403,23 @@ public Expression ApplyProjection(
403403

404404
if (_clientProjections.Count > 0)
405405
{
406-
if (_clientProjections.Any(e => e is ShapedQueryExpression)
407-
&& (Limit != null
406+
EntityShaperNullableMarkingExpressionVisitor? entityShaperNullableMarkingExpressionVisitor = null;
407+
if (_clientProjections.Any(e => e is ShapedQueryExpression))
408+
{
409+
if (Limit != null
408410
|| Offset != null
409411
|| IsDistinct
410-
|| GroupBy.Count > 0))
411-
{
412-
PushdownIntoSubqueryInternal();
412+
|| GroupBy.Count > 0)
413+
{
414+
PushdownIntoSubqueryInternal();
415+
}
416+
entityShaperNullableMarkingExpressionVisitor = new EntityShaperNullableMarkingExpressionVisitor();
413417
}
414418

415-
var projectionCount = _clientProjections.Count;
416419
var newClientProjections = new List<Expression>();
417-
var clientProjectionIndexMap = new object[projectionCount];
420+
var clientProjectionIndexMap = new List<object>();
418421
var remappingRequired = false;
419-
for (var i = 0; i < projectionCount; i++)
422+
for (var i = 0; i < _clientProjections.Count; i++)
420423
{
421424
var value = _clientProjections[i];
422425
switch (value)
@@ -425,7 +428,7 @@ public Expression ApplyProjection(
425428
{
426429
var result = AddEntityProjection(entityProjection);
427430
newClientProjections.Add(result);
428-
clientProjectionIndexMap[i] = newClientProjections.Count - 1;
431+
clientProjectionIndexMap.Add(newClientProjections.Count - 1);
429432

430433
break;
431434
}
@@ -434,7 +437,7 @@ public Expression ApplyProjection(
434437
{
435438
var result = Constant(AddToProjection(sqlExpression, _aliasForClientProjections[i]));
436439
newClientProjections.Add(result);
437-
clientProjectionIndexMap[i] = newClientProjections.Count - 1;
440+
clientProjectionIndexMap.Add(newClientProjections.Count - 1);
438441

439442
break;
440443
}
@@ -485,12 +488,18 @@ public Expression ApplyProjection(
485488
innerShaperExpression);
486489
}
487490

488-
innerShaperExpression = innerSelectExpression.ApplyProjection(
489-
innerShaperExpression, shapedQueryExpression.ResultCardinality, querySplittingBehavior);
490491
AddJoin(JoinType.OuterApply, ref innerSelectExpression);
491-
492-
innerShaperExpression = CopyProjectionToOuter(innerSelectExpression, innerShaperExpression);
493-
clientProjectionIndexMap[i] = innerShaperExpression;
492+
var offset = _clientProjections.Count;
493+
var count = innerSelectExpression._clientProjections.Count;
494+
_clientProjections.AddRange(innerSelectExpression._clientProjections.Select(e => MakeNullable(e, nullable: true)));
495+
_aliasForClientProjections.AddRange(innerSelectExpression._aliasForClientProjections);
496+
innerShaperExpression = new ProjectionIndexRemappingExpressionVisitor(
497+
innerSelectExpression,
498+
this,
499+
Enumerable.Range(offset, count).ToArray())
500+
.Visit(innerShaperExpression);
501+
innerShaperExpression = entityShaperNullableMarkingExpressionVisitor!.Visit(innerShaperExpression);
502+
clientProjectionIndexMap.Add(innerShaperExpression);
494503
remappingRequired = true;
495504
break;
496505

@@ -651,7 +660,7 @@ static Expression RemoveConvert(Expression expression)
651660
var result = new SplitCollectionInfo(
652661
parentIdentifier, childIdentifier, childIdentifierValueComparers,
653662
innerSelectExpression, innerShaperExpression);
654-
clientProjectionIndexMap[i] = result;
663+
clientProjectionIndexMap.Add(result);
655664
}
656665
else
657666
{
@@ -746,7 +755,7 @@ static Expression RemoveConvert(Expression expression)
746755
parentIdentifier, outerIdentifier, selfIdentifier,
747756
parentIdentifierValueComparers, outerIdentifierValueComparers, selfIdentifierValueComparers,
748757
innerShaperExpression);
749-
clientProjectionIndexMap[i] = result;
758+
clientProjectionIndexMap.Add(result);
750759
}
751760
remappingRequired = true;
752761

@@ -835,8 +844,8 @@ Expression CopyProjectionToOuter(SelectExpression innerSelectExpression, Express
835844

836845
innerSelectExpression._clientProjections.Clear();
837846
innerSelectExpression._aliasForClientProjections.Clear();
838-
innerShaperExpression = new ProjectionIndexRemappingExpressionVisitor(this, indexMap).Visit(innerShaperExpression);
839-
innerShaperExpression = new EntityShaperNullableMarkingExpressionVisitor().Visit(innerShaperExpression);
847+
innerShaperExpression = new ProjectionIndexRemappingExpressionVisitor(innerSelectExpression, this, indexMap).Visit(innerShaperExpression);
848+
innerShaperExpression = entityShaperNullableMarkingExpressionVisitor!.Visit(innerShaperExpression);
840849

841850
return innerShaperExpression;
842851
}
@@ -1784,7 +1793,7 @@ private Expression AddJoin(
17841793
innerSelectExpression._clientProjections.Clear();
17851794
innerSelectExpression._aliasForClientProjections.Clear();
17861795

1787-
innerShaper = new ProjectionIndexRemappingExpressionVisitor(this, indexMap).Visit(innerShaper);
1796+
innerShaper = new ProjectionIndexRemappingExpressionVisitor(innerSelectExpression, this, indexMap).Visit(innerShaper);
17881797
}
17891798
else
17901799
{
@@ -1814,7 +1823,7 @@ private Expression AddJoin(
18141823
innerSelectExpression._clientProjections.Clear();
18151824
innerSelectExpression._aliasForClientProjections.Clear();
18161825

1817-
innerShaper = new ProjectionIndexRemappingExpressionVisitor(this, indexMap).Visit(innerShaper);
1826+
innerShaper = new ProjectionIndexRemappingExpressionVisitor(innerSelectExpression, this, indexMap).Visit(innerShaper);
18181827
}
18191828
else
18201829
{

test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsCollectionsQuerySqlServerTest.cs

Lines changed: 39 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,7 +1091,7 @@ public override async Task Lift_projection_mapping_when_pushing_down_subquery(bo
10911091
AssertSql(
10921092
@"@__p_0='25'
10931093
1094-
SELECT [t].[Id], [t0].[Id], [t0].[c], [l1].[Id]
1094+
SELECT [t].[Id], [t0].[Id], [l1].[Id], [t0].[c]
10951095
FROM (
10961096
SELECT TOP(@__p_0) [l].[Id]
10971097
FROM [LevelOne] AS [l]
@@ -1142,49 +1142,47 @@ public override async Task Select_subquery_single_nested_subquery(bool async)
11421142
await base.Select_subquery_single_nested_subquery(async);
11431143

11441144
AssertSql(
1145-
@"SELECT [t1].[Id], [t1].[Id0], [t1].[c]
1145+
@"SELECT [l].[Id], [t0].[Id], [t1].[Id], [t0].[c]
11461146
FROM [LevelOne] AS [l]
1147-
OUTER APPLY (
1148-
SELECT [t].[Id], [t0].[Id] AS [Id0], [t].[c]
1147+
LEFT JOIN (
1148+
SELECT [t].[c], [t].[Id], [t].[OneToMany_Optional_Inverse2Id]
11491149
FROM (
1150-
SELECT TOP(1) 1 AS [c], [l0].[Id]
1150+
SELECT 1 AS [c], [l0].[Id], [l0].[OneToMany_Optional_Inverse2Id], ROW_NUMBER() OVER(PARTITION BY [l0].[OneToMany_Optional_Inverse2Id] ORDER BY [l0].[Id]) AS [row]
11511151
FROM [LevelTwo] AS [l0]
1152-
WHERE [l].[Id] = [l0].[OneToMany_Optional_Inverse2Id]
1153-
ORDER BY [l0].[Id]
11541152
) AS [t]
1155-
LEFT JOIN (
1156-
SELECT [l1].[Id], [l1].[OneToMany_Optional_Inverse3Id]
1157-
FROM [LevelThree] AS [l1]
1158-
) AS [t0] ON [t].[Id] = [t0].[OneToMany_Optional_Inverse3Id]
1159-
) AS [t1]
1160-
ORDER BY [l].[Id]");
1153+
WHERE [t].[row] <= 1
1154+
) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id]
1155+
LEFT JOIN (
1156+
SELECT [l1].[Id], [l1].[OneToMany_Optional_Inverse3Id]
1157+
FROM [LevelThree] AS [l1]
1158+
) AS [t1] ON [t0].[Id] = [t1].[OneToMany_Optional_Inverse3Id]
1159+
ORDER BY [l].[Id], [t0].[Id], [t1].[Id]");
11611160
}
11621161

11631162
public override async Task Select_subquery_single_nested_subquery2(bool async)
11641163
{
11651164
await base.Select_subquery_single_nested_subquery2(async);
11661165

11671166
AssertSql(
1168-
@"SELECT [l].[Id], [t2].[Id], [t2].[Id0], [t2].[c], [t2].[Id1]
1167+
@"SELECT [l].[Id], [t2].[Id], [t2].[Id0], [t2].[Id1], [t2].[c]
11691168
FROM [LevelOne] AS [l]
11701169
LEFT JOIN (
1171-
SELECT [t1].[Id], [t1].[Id0], [t1].[c], [l0].[Id] AS [Id1], [l0].[OneToMany_Optional_Inverse2Id]
1170+
SELECT [l0].[Id], [t0].[Id] AS [Id0], [t1].[Id] AS [Id1], [t0].[c], [l0].[OneToMany_Optional_Inverse2Id]
11721171
FROM [LevelTwo] AS [l0]
1173-
OUTER APPLY (
1174-
SELECT [t].[Id], [t0].[Id] AS [Id0], [t].[c]
1172+
LEFT JOIN (
1173+
SELECT [t].[c], [t].[Id], [t].[OneToMany_Optional_Inverse3Id]
11751174
FROM (
1176-
SELECT TOP(1) 1 AS [c], [l1].[Id]
1175+
SELECT 1 AS [c], [l1].[Id], [l1].[OneToMany_Optional_Inverse3Id], ROW_NUMBER() OVER(PARTITION BY [l1].[OneToMany_Optional_Inverse3Id] ORDER BY [l1].[Id]) AS [row]
11771176
FROM [LevelThree] AS [l1]
1178-
WHERE [l0].[Id] = [l1].[OneToMany_Optional_Inverse3Id]
1179-
ORDER BY [l1].[Id]
11801177
) AS [t]
1181-
LEFT JOIN (
1182-
SELECT [l2].[Id], [l2].[OneToMany_Optional_Inverse4Id]
1183-
FROM [LevelFour] AS [l2]
1184-
) AS [t0] ON [t].[Id] = [t0].[OneToMany_Optional_Inverse4Id]
1185-
) AS [t1]
1178+
WHERE [t].[row] <= 1
1179+
) AS [t0] ON [l0].[Id] = [t0].[OneToMany_Optional_Inverse3Id]
1180+
LEFT JOIN (
1181+
SELECT [l2].[Id], [l2].[OneToMany_Optional_Inverse4Id]
1182+
FROM [LevelFour] AS [l2]
1183+
) AS [t1] ON [t0].[Id] = [t1].[OneToMany_Optional_Inverse4Id]
11861184
) AS [t2] ON [l].[Id] = [t2].[OneToMany_Optional_Inverse2Id]
1187-
ORDER BY [l].[Id], [t2].[Id1], [t2].[Id], [t2].[Id0]");
1185+
ORDER BY [l].[Id], [t2].[Id], [t2].[Id0], [t2].[Id1]");
11881186
}
11891187

11901188
public override async Task Filtered_include_basic_Where(bool async)
@@ -1710,25 +1708,26 @@ public override async Task Complex_query_with_let_collection_projection_FirstOrD
17101708
await base.Complex_query_with_let_collection_projection_FirstOrDefault(async);
17111709

17121710
AssertSql(
1713-
@"SELECT [t1].[Id], [t1].[Name], [t1].[Id0], [t1].[c]
1711+
@"SELECT [l].[Id], [t0].[Id], [t1].[Name], [t1].[Id], [t0].[c]
17141712
FROM [LevelOne] AS [l]
1715-
OUTER APPLY (
1716-
SELECT [t].[Id], [t0].[Name], [t0].[Id] AS [Id0], [t].[c]
1713+
LEFT JOIN (
1714+
SELECT [t].[c], [t].[Id], [t].[OneToMany_Optional_Inverse2Id]
17171715
FROM (
1718-
SELECT TOP(1) 1 AS [c], [l0].[Id]
1716+
SELECT 1 AS [c], [l0].[Id], [l0].[OneToMany_Optional_Inverse2Id], ROW_NUMBER() OVER(PARTITION BY [l0].[OneToMany_Optional_Inverse2Id] ORDER BY [l0].[Id]) AS [row]
17191717
FROM [LevelTwo] AS [l0]
1720-
WHERE ([l].[Id] = [l0].[OneToMany_Optional_Inverse2Id]) AND (([l0].[Name] <> N'Foo') OR [l0].[Name] IS NULL)
1718+
WHERE ([l0].[Name] <> N'Foo') OR [l0].[Name] IS NULL
17211719
) AS [t]
1722-
OUTER APPLY (
1723-
SELECT [l1].[Name], [l1].[Id]
1724-
FROM [LevelOne] AS [l1]
1725-
WHERE EXISTS (
1726-
SELECT 1
1727-
FROM [LevelTwo] AS [l2]
1728-
WHERE ([l1].[Id] = [l2].[OneToMany_Optional_Inverse2Id]) AND ([l2].[Id] = [t].[Id]))
1729-
) AS [t0]
1720+
WHERE [t].[row] <= 1
1721+
) AS [t0] ON [l].[Id] = [t0].[OneToMany_Optional_Inverse2Id]
1722+
OUTER APPLY (
1723+
SELECT [l1].[Name], [l1].[Id]
1724+
FROM [LevelOne] AS [l1]
1725+
WHERE EXISTS (
1726+
SELECT 1
1727+
FROM [LevelTwo] AS [l2]
1728+
WHERE ([l1].[Id] = [l2].[OneToMany_Optional_Inverse2Id]) AND ([l2].[Id] = [t0].[Id]))
17301729
) AS [t1]
1731-
ORDER BY [l].[Id]");
1730+
ORDER BY [l].[Id], [t0].[Id], [t1].[Id]");
17321731
}
17331732

17341733
public override async Task SelectMany_DefaultIfEmpty_multiple_times_with_joins_projecting_a_collection(bool async)

test/EFCore.SqlServer.FunctionalTests/Query/ComplexNavigationsQuerySqlServerTest.cs

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3108,34 +3108,32 @@ public override void Member_pushdown_chain_3_levels_deep_entity()
31083108
base.Member_pushdown_chain_3_levels_deep_entity();
31093109

31103110
AssertSql(
3111-
@"SELECT [t4].[Id], [t4].[Level3_Optional_Id], [t4].[Level3_Required_Id], [t4].[Name], [t4].[OneToMany_Optional_Inverse4Id], [t4].[OneToMany_Optional_Self_Inverse4Id], [t4].[OneToMany_Required_Inverse4Id], [t4].[OneToMany_Required_Self_Inverse4Id], [t4].[OneToOne_Optional_PK_Inverse4Id], [t4].[OneToOne_Optional_Self4Id], [t4].[c], [t4].[c0]
3111+
@"SELECT [t0].[c], [t1].[c], [t3].[Id], [t3].[Level3_Optional_Id], [t3].[Level3_Required_Id], [t3].[Name], [t3].[OneToMany_Optional_Inverse4Id], [t3].[OneToMany_Optional_Self_Inverse4Id], [t3].[OneToMany_Required_Inverse4Id], [t3].[OneToMany_Required_Self_Inverse4Id], [t3].[OneToOne_Optional_PK_Inverse4Id], [t3].[OneToOne_Optional_Self4Id]
31123112
FROM [LevelOne] AS [l]
3113-
OUTER APPLY (
3114-
SELECT [t2].[Id], [t2].[Level3_Optional_Id], [t2].[Level3_Required_Id], [t2].[Name], [t2].[OneToMany_Optional_Inverse4Id], [t2].[OneToMany_Optional_Self_Inverse4Id], [t2].[OneToMany_Required_Inverse4Id], [t2].[OneToMany_Required_Self_Inverse4Id], [t2].[OneToOne_Optional_PK_Inverse4Id], [t2].[OneToOne_Optional_Self4Id], [t2].[c], [t].[c] AS [c0]
3113+
LEFT JOIN (
3114+
SELECT [t].[c], [t].[Id], [t].[Level1_Optional_Id]
31153115
FROM (
3116-
SELECT TOP(1) 1 AS [c], [l0].[Id]
3116+
SELECT 1 AS [c], [l0].[Id], [l0].[Level1_Optional_Id], ROW_NUMBER() OVER(PARTITION BY [l0].[Level1_Optional_Id] ORDER BY [l0].[Id]) AS [row]
31173117
FROM [LevelTwo] AS [l0]
3118-
WHERE [l0].[Level1_Optional_Id] = [l].[Id]
3119-
ORDER BY [l0].[Id]
31203118
) AS [t]
3121-
OUTER APPLY (
3122-
SELECT [t1].[Id], [t1].[Level3_Optional_Id], [t1].[Level3_Required_Id], [t1].[Name], [t1].[OneToMany_Optional_Inverse4Id], [t1].[OneToMany_Optional_Self_Inverse4Id], [t1].[OneToMany_Required_Inverse4Id], [t1].[OneToMany_Required_Self_Inverse4Id], [t1].[OneToOne_Optional_PK_Inverse4Id], [t1].[OneToOne_Optional_Self4Id], [t0].[c]
3123-
FROM (
3124-
SELECT TOP(1) 1 AS [c], [l1].[Id]
3125-
FROM [LevelThree] AS [l1]
3126-
WHERE [l1].[Level2_Required_Id] = [t].[Id]
3127-
ORDER BY [l1].[Id]
3128-
) AS [t0]
3129-
LEFT JOIN (
3130-
SELECT [t3].[Id], [t3].[Level3_Optional_Id], [t3].[Level3_Required_Id], [t3].[Name], [t3].[OneToMany_Optional_Inverse4Id], [t3].[OneToMany_Optional_Self_Inverse4Id], [t3].[OneToMany_Required_Inverse4Id], [t3].[OneToMany_Required_Self_Inverse4Id], [t3].[OneToOne_Optional_PK_Inverse4Id], [t3].[OneToOne_Optional_Self4Id]
3131-
FROM (
3132-
SELECT [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], ROW_NUMBER() OVER(PARTITION BY [l2].[Level3_Required_Id] ORDER BY [l2].[Id]) AS [row]
3133-
FROM [LevelFour] AS [l2]
3134-
) AS [t3]
3135-
WHERE [t3].[row] <= 1
3136-
) AS [t1] ON [t0].[Id] = [t1].[Level3_Required_Id]
3119+
WHERE [t].[row] <= 1
3120+
) AS [t0] ON [l].[Id] = [t0].[Level1_Optional_Id]
3121+
LEFT JOIN (
3122+
SELECT [t2].[c], [t2].[Id], [t2].[Level2_Required_Id]
3123+
FROM (
3124+
SELECT 1 AS [c], [l1].[Id], [l1].[Level2_Required_Id], ROW_NUMBER() OVER(PARTITION BY [l1].[Level2_Required_Id] ORDER BY [l1].[Id]) AS [row]
3125+
FROM [LevelThree] AS [l1]
31373126
) AS [t2]
3138-
) AS [t4]
3127+
WHERE [t2].[row] <= 1
3128+
) AS [t1] ON [t0].[Id] = [t1].[Level2_Required_Id]
3129+
LEFT JOIN (
3130+
SELECT [t4].[Id], [t4].[Level3_Optional_Id], [t4].[Level3_Required_Id], [t4].[Name], [t4].[OneToMany_Optional_Inverse4Id], [t4].[OneToMany_Optional_Self_Inverse4Id], [t4].[OneToMany_Required_Inverse4Id], [t4].[OneToMany_Required_Self_Inverse4Id], [t4].[OneToOne_Optional_PK_Inverse4Id], [t4].[OneToOne_Optional_Self4Id]
3131+
FROM (
3132+
SELECT [l2].[Id], [l2].[Level3_Optional_Id], [l2].[Level3_Required_Id], [l2].[Name], [l2].[OneToMany_Optional_Inverse4Id], [l2].[OneToMany_Optional_Self_Inverse4Id], [l2].[OneToMany_Required_Inverse4Id], [l2].[OneToMany_Required_Self_Inverse4Id], [l2].[OneToOne_Optional_PK_Inverse4Id], [l2].[OneToOne_Optional_Self4Id], ROW_NUMBER() OVER(PARTITION BY [l2].[Level3_Required_Id] ORDER BY [l2].[Id]) AS [row]
3133+
FROM [LevelFour] AS [l2]
3134+
) AS [t4]
3135+
WHERE [t4].[row] <= 1
3136+
) AS [t3] ON [t1].[Id] = [t3].[Level3_Required_Id]
31393137
ORDER BY [l].[Id]");
31403138
}
31413139

0 commit comments

Comments
 (0)