How to avoid Cte simplification
See original GitHub issueSometimes when I’m composing a tree of Ctes, I get cte duplicates. I think that the issue is caused by some sort of Cte simplification done by linq2db. For example if a have a Cte like this:
-- Wip Oracle.Managed Oracle12
DECLARE @startDateTime TimeStamp -- DateTime
SET @startDateTime = TO_TIMESTAMP('2019-07-22 07:34:52.000000', 'YYYY-MM-DD HH24:MI:SS.FF6')
DECLARE @endDateTime TimeStamp -- DateTime
SET @endDateTime = TO_TIMESTAMP('2019-07-23 07:34:52.000000', 'YYYY-MM-DD HH24:MI:SS.FF6')
WITH SerialTested
(
Site,
Sfc,
SfcBo,
ShopOrderBo,
ItemBo,
MasterOperationBo,
ResourceBo,
WorkCenterBo,
DateTime,
Type
)
AS
(
SELECT
zmeHstTest.SITE as Site,
zmeHstTest.SFC as Sfc,
zmeHstTest.SFC_BO as SfcBo,
zmeHstTest.SHOP_ORDER_BO as ShopOrderBo,
zmeHstTest.ITEM_BO as ItemBo,
zmeHstTest.OPERATION_BO as MasterOperationBo,
zmeHstTest.RESOURCE_BO as ResourceBo,
zmeHstTest.WORK_CENTER_BO as WorkCenterBo,
zmeHstTest.DATE_TIME as DateTime,
zmeHstTest.TYPE as Type_1
FROM
ZME_HST_TEST zmeHstTest
WHERE
zmeHstTest.ORT = 'false' AND zmeHstTest.DATE_TIME >= CAST(:startDateTime AS DATE) AND
zmeHstTest.DATE_TIME <= CAST(:endDateTime AS DATE)
)
SELECT
t1.Site,
t1.Sfc,
t1.SfcBo,
t1.ShopOrderBo,
t1.ItemBo,
t1.MasterOperationBo,
t1.ResourceBo,
t1.WorkCenterBo,
t1.DateTime,
t1.Type as Type_1
FROM
SerialTested t1
when I use it in another Cte I get:
-- Wip Oracle.Managed Oracle12
DECLARE @startDateTime TimeStamp -- DateTime
SET @startDateTime = TO_TIMESTAMP('2019-07-22 07:34:52.000000', 'YYYY-MM-DD HH24:MI:SS.FF6')
DECLARE @endDateTime TimeStamp -- DateTime
SET @endDateTime = TO_TIMESTAMP('2019-07-23 07:34:52.000000', 'YYYY-MM-DD HH24:MI:SS.FF6')
WITH SerialTested (MasterOperationBo, Site)
AS
(
SELECT
zmeHstTest.OPERATION_BO as MasterOperationBo,
zmeHstTest.SITE as Site
FROM
ZME_HST_TEST zmeHstTest
WHERE
zmeHstTest.ORT = 'false' AND zmeHstTest.DATE_TIME >= CAST(:startDateTime AS DATE) AND
zmeHstTest.DATE_TIME <= CAST(:endDateTime AS DATE)
),
DistinctOperationBo (MasterOperationBo, Site)
AS
(
SELECT DISTINCT
serialTested_1.MasterOperationBo,
serialTested_1.Site
FROM
SerialTested serialTested_1
)
SELECT
t1.MasterOperationBo,
t1.Site
FROM
DistinctOperationBo t1
The problem is that in the final query I get 2 duplicates of SerialTested, SerialTested0 and SerialTested1 with a duplicate of corresponding parameters:
-- Wip Oracle.Managed Oracle12
DECLARE @startDateTime_1 TimeStamp -- DateTime
SET @startDateTime_1 = TO_TIMESTAMP('2019-07-22 07:34:52.000000', 'YYYY-MM-DD HH24:MI:SS.FF6')
DECLARE @endDateTime_1 TimeStamp -- DateTime
SET @endDateTime_1 = TO_TIMESTAMP('2019-07-23 07:34:52.000000', 'YYYY-MM-DD HH24:MI:SS.FF6')
DECLARE @startDateTime_2 TimeStamp -- DateTime
SET @startDateTime_2 = TO_TIMESTAMP('2019-07-22 07:34:52.000000', 'YYYY-MM-DD HH24:MI:SS.FF6')
DECLARE @endDateTime_2 TimeStamp -- DateTime
SET @endDateTime_2 = TO_TIMESTAMP('2019-07-23 07:34:52.000000', 'YYYY-MM-DD HH24:MI:SS.FF6')
WITH SerialTested0
(
SfcBo,
MasterOperationBo,
ShopOrderBo,
ResourceBo,
WorkCenterBo,
Site,
Sfc,
DateTime,
Type
)
AS
(
SELECT
zmeHstTest_1.SFC_BO as SfcBo,
zmeHstTest_1.OPERATION_BO as MasterOperationBo,
zmeHstTest_1.SHOP_ORDER_BO as ShopOrderBo,
zmeHstTest_1.RESOURCE_BO as ResourceBo,
zmeHstTest_1.WORK_CENTER_BO as WorkCenterBo,
zmeHstTest_1.SITE as Site,
zmeHstTest_1.SFC as Sfc,
zmeHstTest_1.DATE_TIME as DateTime,
zmeHstTest_1.TYPE as Type_1
FROM
ZME_HST_TEST zmeHstTest_1
WHERE
zmeHstTest_1.ORT = 'false' AND zmeHstTest_1.DATE_TIME >= CAST(:startDateTime_1 AS DATE) AND
zmeHstTest_1.DATE_TIME <= CAST(:endDateTime_1 AS DATE)
),
SerialTested1 (MasterOperationBo, Site)
AS
(
SELECT
zmeHstTest_2.OPERATION_BO as MasterOperationBo,
zmeHstTest_2.SITE as Site
FROM
ZME_HST_TEST zmeHstTest_2
WHERE
zmeHstTest_2.ORT = 'false' AND zmeHstTest_2.DATE_TIME >= CAST(:startDateTime_2 AS DATE) AND
zmeHstTest_2.DATE_TIME <= CAST(:endDateTime_2 AS DATE)
),
ItemGroupMembers (RowNumber, ItemBo, ItemGroupBo)
AS
(
SELECT
ROW_NUMBER() OVER(PARTITION BY itemGroupMember.ITEM_BO ORDER BY itemGroupMember.ITEM_GROUP_BO) as RowNumber,
itemGroupMember.ITEM_BO as ItemBo,
itemGroupMember.ITEM_GROUP_BO as ItemGroupBo
FROM
ITEM_GROUP_MEMBER itemGroupMember
),
FindRouterGroups
(
Sequence,
LastRouterSequence,
MasterOperationBo,
ShopOrderBo,
ResourceBo,
WorkCenterBo,
Site,
RouterBo,
Sfc,
SfcBo,
DateTime,
Type
)
AS
(
SELECT
sfcRouter.SEQUENCE as Sequence_1,
MAX(sfcRouter.SEQUENCE) OVER(PARTITION BY sfcRouter.SFC_ROUTING_BO) as LastRouterSequence,
serialTested_1.MasterOperationBo,
serialTested_1.ShopOrderBo,
serialTested_1.ResourceBo,
serialTested_1.WorkCenterBo,
serialTested_1.Site,
router_1.HANDLE as RouterBo,
serialTested_1.Sfc,
serialTested_1.SfcBo,
serialTested_1.DateTime,
serialTested_1.Type as Type_1
FROM
SerialTested0 serialTested_1
INNER JOIN SFC_ROUTING sfcRouting ON sfcRouting.SFC_BO = serialTested_1.SfcBo
INNER JOIN SFC_ROUTER sfcRouter ON sfcRouter.SFC_ROUTING_BO = sfcRouting.HANDLE
INNER JOIN ROUTER router_1 ON router_1.HANDLE = sfcRouter.ROUTER_BO
WHERE
(sfcRouter.COMPLETED = 'false' AND sfcRouter.IN_USE = 'true' OR sfcRouter.COMPLETED = 'true')
),
DistinctOperationBo (MasterOperationBo, Site)
AS
(
SELECT DISTINCT
serialTested_2.MasterOperationBo,
serialTested_2.Site
FROM
SerialTested1 serialTested_2
),
FirstItemGroupMember (ItemBo, ItemGroupBo)
AS
(
SELECT
itemGroupMembers_1.ItemBo,
itemGroupMembers_1.ItemGroupBo
FROM
ItemGroupMembers itemGroupMembers_1
WHERE
itemGroupMembers_1.RowNumber = 1
),
FindRouter
(
MasterOperationBo,
ShopOrderBo,
ResourceBo,
WorkCenterBo,
Site,
RouterBo,
Sfc,
SfcBo,
DateTime,
Type
)
AS
(
SELECT
findRouterGroups_1.MasterOperationBo,
findRouterGroups_1.ShopOrderBo,
findRouterGroups_1.ResourceBo,
findRouterGroups_1.WorkCenterBo,
findRouterGroups_1.Site,
findRouterGroups_1.RouterBo,
findRouterGroups_1.Sfc,
findRouterGroups_1.SfcBo,
findRouterGroups_1.DateTime,
findRouterGroups_1.Type as Type_1
FROM
FindRouterGroups findRouterGroups_1
WHERE
findRouterGroups_1.Sequence = findRouterGroups_1.LastRouterSequence
),
DistinctOperationData
(
MasterOperationBo,
OperationBo,
Operation,
Revision,
Description
)
AS
(
SELECT
distinctOperationBo_1.MasterOperationBo,
operation_2.HANDLE as OperationBo,
operation_2.OPERATION as Operation_1,
operation_2.REVISION as Revision,
operation_2.DESCRIPTION as Description
FROM
DistinctOperationBo distinctOperationBo_1
INNER JOIN OPERATION operation_2 ON distinctOperationBo_1.Site = operation_2.SITE AND operation_2.HANDLE LIKE REPLACE(distinctOperationBo_1.MasterOperationBo, '#', '%') AND operation_2.CURRENT_REVISION = 'true'
),
RouterOperationTestCategory (MasterOperationBo, RouterBo, TestCategory)
AS
(
SELECT
distinctOperationBo_2.MasterOperationBo,
routerStep.ROUTER_BO as RouterBo,
customFields_1.VALUE as TestCategory
FROM
DistinctOperationBo distinctOperationBo_2
INNER JOIN ROUTER_OPERATION routerOperation ON distinctOperationBo_2.MasterOperationBo = routerOperation.OPERATION_BO
INNER JOIN CUSTOM_FIELDS customFields_1 ON customFields_1.HANDLE = routerOperation.HANDLE AND customFields_1.ATTRIBUTE = 'TEST_CATEGORY'
INNER JOIN ROUTER_STEP routerStep ON routerStep.HANDLE = routerOperation.ROUTER_STEP_BO
),
GetAdditionalData
(
Site,
SiteDescription,
Sfc,
SfcBo,
Qty,
ShopOrderBo,
ShopOrder,
ItemBo,
Item,
ItemDescription,
ItemRevision,
ItemGroup,
ItemGroupDescription,
ProductLine,
ProductGroup,
ProductHierarchy,
OperationBo,
Operation,
OperationRevision,
OperationDescription,
ResourceBo,
Resrce,
ResrceDescription,
WorkCenterBo,
WorkCenter,
WorkCenterDescription,
Line,
LineDescription,
DateTime,
Type,
TestCategory
)
AS
(
SELECT
findRouter_1.Site,
site_1.DESCRIPTION as SiteDescription,
findRouter_1.Sfc,
findRouter_1.SfcBo,
1 as Qty,
findRouter_1.ShopOrderBo,
shopOrder_1.SHOP_ORDER as ShopOrder,
item_1.HANDLE as ItemBo,
item_1.ITEM as Item,
item_1.DESCRIPTION as ItemDescription,
item_1.REVISION as ItemRevision,
itemGroup_1.ITEM_GROUP as ItemGroup,
itemGroup_1.DESCRIPTION as ItemGroupDescription,
customFields_2.VALUE as ProductLine,
customFields2.VALUE as ProductGroup,
customFields3.VALUE as ProductHierarchy,
distinctOperationData_1.OperationBo,
distinctOperationData_1.Operation as Operation_1,
distinctOperationData_1.Revision as OperationRevision,
distinctOperationData_1.Description as OperationDescription,
findRouter_1.ResourceBo,
resrce_1.RESRCE as Resrce,
resrce_1.DESCRIPTION as ResrceDescription,
findRouter_1.WorkCenterBo,
workCenter_1.WORK_CENTER as WorkCenter,
workCenter_1.DESCRIPTION as WorkCenterDescription,
workCenter2.WORK_CENTER as Line,
workCenter2.DESCRIPTION as LineDescription,
findRouter_1.DateTime,
findRouter_1.Type as Type_1,
routerOperationTestCategory_1.TestCategory
FROM
FindRouter findRouter_1
INNER JOIN DistinctOperationData distinctOperationData_1 ON distinctOperationData_1.MasterOperationBo = findRouter_1.MasterOperationBo
INNER JOIN SHOP_ORDER shopOrder_1 ON shopOrder_1.HANDLE = findRouter_1.ShopOrderBo
INNER JOIN ITEM item_1 ON item_1.HANDLE = shopOrder_1.ITEM_BO
INNER JOIN RESRCE resrce_1 ON resrce_1.HANDLE = findRouter_1.ResourceBo
INNER JOIN WORK_CENTER workCenter_1 ON workCenter_1.HANDLE = findRouter_1.WorkCenterBo
INNER JOIN SITE site_1 ON site_1.SITE = findRouter_1.Site
LEFT JOIN RouterOperationTestCategory routerOperationTestCategory_1 ON routerOperationTestCategory_1.MasterOperationBo = findRouter_1.MasterOperationBo AND routerOperationTestCategory_1.RouterBo = findRouter_1.RouterBo
LEFT JOIN WORK_CENTER_MEMBER workCenterMember ON workCenterMember.WORK_CENTER_OR_RESOURCE_GBO = workCenter_1.HANDLE
LEFT JOIN WORK_CENTER workCenter2 ON workCenter2.HANDLE = workCenterMember.WORK_CENTER_BO
LEFT JOIN FirstItemGroupMember firstItemGroupMember_1 ON firstItemGroupMember_1.ItemBo = item_1.HANDLE
LEFT JOIN ITEM_GROUP itemGroup_1 ON itemGroup_1.HANDLE = firstItemGroupMember_1.ItemGroupBo
LEFT JOIN CUSTOM_FIELDS customFields_2 ON customFields_2.HANDLE = item_1.HANDLE AND customFields_2.ATTRIBUTE = 'PRODUCT_LINE'
LEFT JOIN CUSTOM_FIELDS customFields2 ON customFields2.HANDLE = item_1.HANDLE AND customFields2.ATTRIBUTE = 'SPART'
LEFT JOIN CUSTOM_FIELDS customFields3 ON customFields3.HANDLE = item_1.HANDLE AND customFields3.ATTRIBUTE = 'PRDHA'
)
SELECT
t1.Site,
t1.SiteDescription,
t1.Sfc,
t1.SfcBo,
t1.ShopOrderBo,
t1.ShopOrder,
t1.ItemBo,
t1.Item,
t1.ItemDescription,
t1.ItemRevision,
t1.ItemGroup,
t1.ItemGroupDescription,
t1.ProductLine,
t1.ProductGroup,
t1.ProductHierarchy,
t1.OperationBo,
t1.Operation as Operation_1,
t1.OperationRevision,
t1.OperationDescription,
t1.ResourceBo,
t1.Resrce,
t1.ResrceDescription,
t1.WorkCenterBo,
t1.WorkCenter,
t1.WorkCenterDescription,
t1.Line,
t1.LineDescription,
t1.DateTime,
t1.Type as Type_1,
t1.TestCategory
FROM
GetAdditionalData t1
Is there a way to avoid this type of behavior?
Thank you for your supporto, Filippo.
Environment details
linq2db version: 3.0.0-rc.1984 Database Server: Oracle Database Provider: Oracle.ManagedDataAccess.Core (3.0.0-preview.1) Operating system: Windows 10 .NET Framework:.NET Core 3.1
Issue Analytics
- State:
- Created 3 years ago
- Comments:20 (11 by maintainers)
Top Results From Across the Web
SQL Performance Tips #2
Avoiding running on the heap and CTEs vs Temporary Tables ... CTEs can be a major help in most queries, simplifying the development...
Read more >Common Table Expressions: When and How to Use Them
CTEs, like database views and derived tables, enable users to more easily write and maintain complex queries via increased readability and simplification. This ......
Read more >Is using a CTE to simplify a GROUP BY bad ...
I have to keep the code in the GROUP BY and the SELECT "in step" Let's assume its a lot more complex than...
Read more >Key Notes on SQL CTE and Best Practices
Simplified Syntax: CTE provides a simplified syntax for writing complex ... Avoid using nested CTEs, as they can make the query difficult to...
Read more >How to simplify multiple CTE - sql
1 Answer 1 ... This would avoid multiple passes on the various tables and should run much quicker unless these are highly selective...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Bad idea to cache using SQL text, everything at the end of the projection may change SQL. Linq2db generates CTE fields only if they are needed for final SQL. That’s why generated SQL is highly optimized.
@filippobottega, root of the problem that this can be very specific situation. In some circumstances library can not detect that two the “same” expressions are equal, possibly they were transformed earlier by linq2db itself and has small little difference.
I have created brach #2262 and we can interactively localize problem.