(3504) ошибка при попытке создать сумму в терадате? - PullRequest
1 голос
/ 09 апреля 2020

Я пытаюсь изменить запрос для генерации прогноза будущей работы, чтобы суммировать объем работы, выделенной для определенных сделок, однако я продолжаю получать ошибку 3504, когда добавляю в функцию SUM (). Однако я не уверен, что мне не хватает?

РЕДАКТИРУЕТСЯ: включает группу по и выбирает, не уверен, почему они вообще не скопировали ...

Примечания: Тип столбца для WS.ActivityEstimatedHours - десятичное число

SELECT
        WO.WorkOrderCodeBK AS "WORKORDER",
        WO.WorkOrderPMCodeBK AS "PM",
        WO.WorkOrderDescription AS "DESCRIPTION",
        NULL AS "COMMENTS",
        WO.WorkOrderPlannerNotes AS "PLANNER_COMMENTS",
        WO.WorkOrderStatus AS "STATUS",
        WO.EquipmentOperationsGroup AS "OPSGROUP",
        WO.WorkOrderSurfaceAssetBK AS "DEPARTMENT",
        WO.WorkOrderEquipmentCodeBK AS "EQUIPMENT",
        WO.WorkOrderAssignedToResourceBK AS "ASSIGNED_TO",
        CAST( 
            CAST(WO.WorkOrderPMDueDate AS DATE FORMAT 'MM/DD/YYYY') AS DATE FORMAT 'MM/DD/YYYY')
                                                         AS "PM_ORIGINAL_DUE_DATE",
        SE.EquipmentIC AS "EQUIPMENT_IC",
        WO.WorkOrderDeferralExpirationDate AS "DEFERRAL_EXPERATION_DATE",
        WO.WorkOrderObjCriticality AS "CRITICALITY",
        PM.PMWorkOrderJobType AS "PM_TYPE",
        NULL AS "DEFERRAL_REQUIRED_IF_LATE",
        SE.EquipmentCostCode AS "COST_CODE",
        SE.EquipmentClassBK AS "EQ_CLASS",
        WS.ActivityCode AS "Activity",
        WS.ActivityTradeCodeBK AS "Trade",
        SUM(WS.ActivityEstimatedHours) "HOURS"

FROM     IDW_PL_SURFACEMAINTENANCE.DIMWorkOrder WO 
    JOIN IDW_PL_SURFACEMAINTENANCE.DIMSurfacePM PM ON PM.PMCodeBK = WO.WorkOrderPMCodeBK
    JOIN IDW_PL_SURFACEMAINTENANCE.DIMSurfaceEquipment SE ON SE.EquipmentCodeBK = WO.WorkOrderEquipmentCodeBK
    LEFT JOIN IDW_PL_SURFACEMAINTENANCE.FACTWorkOrderActivity WS ON WS.ActivityWorkOrderCodeBK = WO.WorkOrderCodeBK
WHERE 1=1
AND  DEPARTMENT IN ('CO','CY','KR','LH','MS','SA')
AND  STATUS IN ('R','SCH')
AND  PM IS NOT NULL
AND  PM_ORIGINAL_DUE_DATE >= CURRENT_DATE
AND  PM_ORIGINAL_DUE_DATE <= CURRENT_DATE + 115
AND  WORKORDER IS NOT NULL
GROUP BY WORKORDER, PM , DESCRIPTION, COMMENTS, PLANNER_COMMENTS, STATUS, OPSGROUP, DEPARTMENT, EQUIPMENT, ASSIGNED_TO, PM_ORIGINAL_DUE_DATE, EQUIPMENT_IC, DEFERRAL_EXPERATION_DATE, CRITICALITY, PM_TYPE, DEFERRAL_REQUIRED_IF_LATE, COST_CODE, EQ_CLASS, Activity, Trade, HOURS
ORDER BY DEPARTMENT

1 Ответ

2 голосов
/ 09 апреля 2020

Прямо сейчас вы используете псевдонимы столбцов в GROUP BY. В большинстве операций с ядром базы данных для совокупных запросов GROUP BY обычно предшествует SELECT, поэтому псевдонимы столбцов не будут известны на этом этапе. С учетом сказанного, ORDER следует после SELECT, поэтому можно использовать псевдоним "DEPARTMENT".

Известная ирония SQL заключается в том, что SELECT, который появляется в качестве первого предложения обычно выполняется один из последних шагов. Будучи декларативным по природе, SQL не похож на процедурные языки, которые работают в том порядке, в котором они написаны. Поэтому просто используйте оригинальные нескалярные столбцы в GROUP BY, а не псевдонимы столбцов.

SELECT
        WO.WorkOrderCodeBK AS "WORKORDER",
        WO.WorkOrderPMCodeBK AS "PM",
        WO.WorkOrderDescription AS "DESCRIPTION",
        NULL AS "COMMENTS",
        WO.WorkOrderPlannerNotes AS "PLANNER_COMMENTS",
        WO.WorkOrderStatus AS "STATUS",
        WO.EquipmentOperationsGroup AS "OPSGROUP",
        WO.WorkOrderSurfaceAssetBK AS "DEPARTMENT",
        WO.WorkOrderEquipmentCodeBK AS "EQUIPMENT",
        WO.WorkOrderAssignedToResourceBK AS "ASSIGNED_TO",
        CAST(CAST(WO.WorkOrderPMDueDate AS DATE FORMAT 'MM/DD/YYYY')  
             AS DATE FORMAT 'MM/DD/YYYY') AS "PM_ORIGINAL_DUE_DATE",
        SE.EquipmentIC AS "EQUIPMENT_IC",
        WO.WorkOrderDeferralExpirationDate AS "DEFERRAL_EXPERATION_DATE",
        WO.WorkOrderObjCriticality AS "CRITICALITY",
        PM.PMWorkOrderJobType AS "PM_TYPE",
        NULL AS "DEFERRAL_REQUIRED_IF_LATE",
        SE.EquipmentCostCode AS "COST_CODE",
        SE.EquipmentClassBK AS "EQ_CLASS",
        WS.ActivityCode AS "Activity",
        WS.ActivityTradeCodeBK AS "Trade",
        SUM(WS.ActivityEstimatedHours) AS "HOURS"

FROM     IDW_PL_SURFACEMAINTENANCE.DIMWorkOrder WO 
    INNER JOIN IDW_PL_SURFACEMAINTENANCE.DIMSurfacePM PM ON PM.PMCodeBK = WO.WorkOrderPMCodeBK
    INNER JOIN IDW_PL_SURFACEMAINTENANCE.DIMSurfaceEquipment SE ON SE.EquipmentCodeBK = WO.WorkOrderEquipmentCodeBK
    LEFT JOIN IDW_PL_SURFACEMAINTENANCE.FACTWorkOrderActivity WS ON WS.ActivityWorkOrderCodeBK = WO.WorkOrderCodeBK
WHERE 1=1
  AND  DEPARTMENT IN ('CO','CY','KR','LH','MS','SA')
  AND  STATUS IN ('R','SCH')
  AND  PM IS NOT NULL
  AND  PM_ORIGINAL_DUE_DATE >= CURRENT_DATE
  AND  PM_ORIGINAL_DUE_DATE <= CURRENT_DATE + 115
  AND  WORKORDER IS NOT NULL
GROUP BY 
        WO.WorkOrderCodeBK,
        WO.WorkOrderPMCodeBK,
        WO.WorkOrderDescription,
        WO.WorkOrderPlannerNotes,
        WO.WorkOrderStatus,
        WO.EquipmentOperationsGroup,
        WO.WorkOrderSurfaceAssetBK,
        WO.WorkOrderEquipmentCodeBK,
        WO.WorkOrderAssignedToResourceBK,
        CAST(CAST(WO.WorkOrderPMDueDate AS DATE FORMAT 'MM/DD/YYYY') 
             AS DATE FORMAT 'MM/DD/YYYY'),
        SE.EquipmentIC,
        WO.WorkOrderDeferralExpirationDate,
        WO.WorkOrderObjCriticality,
        PM.PMWorkOrderJobType,
        SE.EquipmentCostCode,
        SE.EquipmentClassBK,
        WS.ActivityCode,
        WS.ActivityTradeCodeBK
ORDER BY "DEPARTMENT"

При ближайшем рассмотрении и, как подтверждает держатель золотой метки Teradata, @dnoeth, Teradata может быть исключением из использования агрегированные псевдонимы столбцов в GROUP BY. Однако OP по ошибке использует вычисленный совокупный псевдоним столбца, "HOURS" в условии GROUP BY, для которого эта ссылка не разрешена и может даже быть избыточной.

...