SQL 根据字段条件和输出总记录数聚合记录的语法

SQL Syntax To Aggregate Records Based on Field Criteria and Output Total Record Counts

SQL 查询 returns table 结果如下所示:

我目前运行生成的SQL这个table如下所列:

SELECT DISTINCT 
    ld.LOAD_ID, lf.ACTUAL_DELIVERY_TS, ld.ORIG_LOC_ID, 
    fsd.PO_TYPE_CODE, fsf.CASE_QTY, 
    CASE 
       WHEN ORIG_LOC_ID IN (6903, 6909, 6912, 7100, 7101, 7183, 7184, 7837, 7840, 7976) 
          THEN 'Centerpoint'
       WHEN ORIG_LOC_ID IN (6061, 6088, 6060, 7042, 7078, 7085, 7086, 7084, 7089, 7093, 7094, 4892, 7628) 
          THEN 'Imports'
       WHEN ORIG_LOC_ID IN (8092, 8098, 9153, 9193, 9195, 9196) 
          THEN 'Returns'
       WHEN ORIG_LOC_ID IN (6005, 6007, 6008, 6014, 6022, 6029, 6041) 
          THEN 'Fashion'
       WHEN ORIG_LOC_ID IN (7006, 7356, 6280, 8240, 8103, 7853, 7005) 
          THEN 'eCom'
       WHEN ORIG_LOC_ID IN (6006, 6009, 6010, 6011, 6012, 6016, 6017, 6018, 6019, 6020, 6021, 6023, 6024, 6025, 6026, 6027, 6030, 6031, 6035, 6036, 6037, 6038, 6039, 6040, 6043, 6048, 6054, 6066, 6068, 6069, 6070, 6080, 6092, 6094, 7026, 7033, 7034, 7035, 7036, 7038, 7039, 7045) 
          THEN 'Regional'
       WHEN ORIG_LOC_ID IN (6042, 6047, 6055, 6056, 6057, 6059, 6062, 6064, 6065, 6071, 6072, 6073, 6074, 6077, 6082, 6083, 6084, 6085, 6090, 6091, 6095, 6096, 6097, 6099, 7010, 7012, 7013, 7014, 7015, 7016, 7017, 7018, 7019, 7021, 7023, 7024, 7025, 7030, 7047, 7048, 7053, 7055, 7068, 7070, 7077, 7079) 
          THEN 'Grocery'
       WHEN ORIG_LOC_TYPE_CODE IN ('VNDR') 
          THEN 'VNDR'
       WHEN ORIG_LOC_TYPE_CODE IN ('STORE') 
          THEN 'STORE'
    END AS LOADORIG, 
    CASE
       WHEN PO_TYPE_CODE IN (23, 33, 3, 53, 45, 73, 93) THEN 'DA'
       WHEN PO_TYPE_CODE IN (20, 22, 28, 29, 40, 42, 50, 83) THEN 'SS'
       WHEN PO_TYPE_CODE IN (10, 11, 12, 13, 14, 15, 16, 17, 18, 19) THEN 'Fashion'
       WHEN PO_TYPE_CODE IN (43) THEN 'XDOCK'
    END AS CHANNEL, 
    ld.DEST_LOC_ID
FROM 
    us_trans_dm_vm.LOAD_DIM ld, 
    us_trans_dm_vm.LOAD_FACT lf, 
    us_trans_dm_vm.FREIGHT_SHIPMENT_FACT fsf, 
    us_trans_dm_vm.FREIGHT_SHIPMENT_DIM fsd
WHERE 
    ld.LOAD_SK_ID = lf.LOAD_SK_ID
    AND lf.LOAD_SK_ID = fsf.LOAD_SK_ID
    AND fsf.SHIPMENT_SK_ID = fsd.SHIPMENT_SK_ID
    AND fsd.CURRENT_IND = 'Y'
    AND ld.CURRENT_IND = 'Y'
    AND ld.DEST_LOC_ID IN (6006, 6009, 6010, 6011, 6012, 6016, 6017, 6018, 6019, 6020, 6021, 6023, 6024, 6025, 6026, 6027, 6030, 6031, 6035, 6036, 6037, 6038, 6039, 6040, 6043, 6048, 6054, 6066, 6068, 6069, 6070, 6080, 6092, 6094, 7026, 7033, 7034, 7035, 7036, 7038, 7039, 7045)
    AND lf.ACTUAL_DELIVERY_TS BETWEEN '2016-02-01 00:00:00' AND '2016-07-31 23:59:59'

LOAD_ID 是唯一的记录标识符,每个 LOAD_ID 都有不同的 PO 类型和与之关联的案例计数。我正在尝试找到一种方法来根据 PO 类型和案例计数的一些标准来聚合 LOAD_ID 行:

例如 - 如果 PO_TYPE_CODE 20 的 CASE_QTY 大于与该 LOAD_ID 关联的总数 CASE_QTY 的 50%,则计数 LOAD_ID 30604179 "TEST"

如果 PO_TYPE_CODE 33 的 CASE_QTY 大于与该 LOAD_ID 相关联的总数 CASE_QTY 的 25%,则计数 LOAD_ID 30604179 为 "TEST 2"

期望输出:

如有任何帮助或指导,我们将不胜感激!!!!

我认为,如果您的标准始终基于与 LOAD_ID 相关联的总数 CASE_QTY,那么您只需要加入该结果,以便您可以比较每个值,例如:

SELECT DISTINCT 
    ld.LOAD_ID, ... fsf.CASE_QTY, 100.00 * CASE_QTY/sum_caseQty AS loadCaseQtyPct,
    ...
FROM 
    us_trans_dm_vm.LOAD_DIM ld INNER JOIN
    us_trans_dm_vm.LOAD_FACT lf ON
        ld.LOAD_SK_ID = lf.LOAD_SK_ID INNER JOIN
    us_trans_dm_vm.FREIGHT_SHIPMENT_FACT fsf ON
     lf.LOAD_SK_ID = fsf.LOAD_SK_ID INNER JOIN  
    us_trans_dm_vm.FREIGHT_SHIPMENT_DIM fsd ON
     fsf.SHIPMENT_SK_ID = fsd.SHIPMENT_SK_ID INNER JOIN
     (SELECT
     loadid, SUM(case_qty) AS sum_caseQty
     FROM
     us_trans_dm_vm.LOAD_DIM
     GROUP BY 1) cq ON
     ld.loadid = cq.loadid
WHERE 
     fsd.CURRENT_IND = 'Y'
    AND ld.CURRENT_IND = 'Y'
    AND ld.DEST_LOC_ID IN (6006, 6009, 6010, 6011, 6012, 6016, 6017, 6018, 6019, 6020, 6021, 6023, 6024, 6025, 6026, 6027, 6030, 6031, 6035, 6036, 6037, 6038, 6039, 6040, 6043, 6048, 6054, 6066, 6068, 6069, 6070, 6080, 6092, 6094, 7026, 7033, 7034, 7035, 7036, 7038, 7039, 7045)
    AND lf.ACTUAL_DELIVERY_TS BETWEEN '2016-02-01 00:00:00' AND '2016-07-31 23:59:59'

您可以使用 window 函数来实现这一点。类似于:

 CASE 
    WHEN POT_TYPE_CODE = 20 AND Cast(CASE_QTY AS DECIMAL(4,2)/SUM(CAST(CASE_QTY AS DECIMAL(4,2)) OVER (PARTITION BY LOAD_ID) > .5 
        THEN 'Test' 
    WHEN PO_TYPE_CODE = 33 AND Cast(CASE_QTY AS DECIMAL(4,2)/SUM(CAST(CASE_QTY AS DECIMAL(4,2)) OVER (PARTITION BY LOAD_ID) > .25 
        THEN 'Test 2' 
    END as my_new_field

window 函数 Sum(Case_QTY) OVER (PARTITION BY LOAD_ID) 将对 load_id 和 return 结果的中间结果集中的所有行求和。将当前记录分成 case_qty 可以得到可以测试的百分比。

此外,我将 case_qty 转换为十进制以确保除法结果为十进制。否则它可能会四舍五入为整数...不记得那是如何计算的,所以它可能是不必要的。

@JNevill

我已经根据我需要的输出调整了 window 函数。我不再需要使用上述 50%/25% 的标准来解决问题。相反,我使用 window 函数来计算每一行的 Case_QTY 百分比与整体 Load_ID 的 Case_Qty 相比。我现在得到如下图所示的结果。

使用这个 SQL:

SELECT 
DISTINCT ld.LOAD_ID,lf.ACTUAL_DELIVERY_TS,ld.ORIG_LOC_ID,fsd.PO_TYPE_CODE,fsf.CASE_QTY,

CASE 
WHEN ORIG_LOC_ID IN (6903,6909,6912,7100,7101,7183,7184,7837,7840,7976) THEN 'Centerpoint'
WHEN ORIG_LOC_ID IN (6061,6088,6060,7042,7078,7085,7086,7084,7089,7093,7094,4892,7628) THEN 'Imports'
WHEN ORIG_LOC_ID IN (8092,8098,9153,9193,9195,9196) THEN 'Returns'
WHEN ORIG_LOC_ID IN (6005,6007,6008,6014,6022,6029,6041) THEN 'Fashion'
WHEN ORIG_LOC_ID IN (7006,7356,6280,8240,8103,7853,7005) THEN 'eCom'
WHEN ORIG_LOC_ID IN (6006, 6009, 6010, 6011, 6012, 6016, 6017, 6018, 6019, 6020, 6021, 6023, 6024, 6025, 6026, 6027, 6030, 6031, 6035, 6036, 6037, 6038, 6039, 6040, 6043, 6048, 6054, 6066, 6068, 6069, 6070, 6080, 6092, 6094, 7026, 7033, 7034, 7035, 7036, 7038, 7039, 7045) THEN 'Regional'
WHEN ORIG_LOC_ID IN (6042, 6047, 6055, 6056, 6057, 6059, 6062, 6064, 6065, 6071, 6072, 6073, 6074, 6077, 6082, 6083, 6084, 6085, 6090, 6091, 6095, 6096, 6097, 6099, 7010, 7012, 7013, 7014, 7015, 7016, 7017, 7018, 7019, 7021, 7023, 7024, 7025, 7030, 7047, 7048, 7053, 7055, 7068, 7070, 7077, 7079) THEN 'Grocery'
WHEN ORIG_LOC_TYPE_CODE IN ('VNDR') THEN 'VNDR'
WHEN ORIG_LOC_TYPE_CODE IN ('STORE') THEN 'STORE'
END AS LOADORIG, 

CASE
WHEN PO_TYPE_CODE IN (23,33,3,53,45,73,93) THEN 'DA'
WHEN PO_TYPE_CODE IN (20,22,28,29,40,42,50,83) THEN 'SS'
WHEN PO_TYPE_CODE IN (10,11,12,13,14,15,16,17,18,19) THEN 'Fashion'
WHEN PO_TYPE_CODE IN (43) THEN 'XDOCK'
END AS CHANNEL,


CASE 
WHEN Channel = 'DA' THEN  CAST (CASE_QTY AS DECIMAL(38,0))/SUM(CAST(CASE_QTY AS DECIMAL(38,2))) OVER (PARTITION BY ld.LOAD_ID)
WHEN Channel = 'SS' THEN  CAST (CASE_QTY AS DECIMAL(38,0))/SUM(CAST(CASE_QTY AS DECIMAL(38,2))) OVER (PARTITION BY ld.LOAD_ID)
END AS New_Column,

ld.DEST_LOC_ID

FROM us_trans_dm_vm.LOAD_DIM ld,
             us_trans_dm_vm.LOAD_FACT lf,
             us_trans_dm_vm.FREIGHT_SHIPMENT_FACT fsf,
             us_trans_dm_vm.FREIGHT_SHIPMENT_DIM fsd

WHERE ld.LOAD_SK_ID = lf.LOAD_SK_ID
AND lf.LOAD_SK_ID = fsf.LOAD_SK_ID
AND fsf.SHIPMENT_SK_ID = fsd.SHIPMENT_SK_ID
AND fsd.CURRENT_IND = 'Y'
AND ld.CURRENT_IND = 'Y'
AND ld.DEST_LOC_ID IN (6006)
AND lf.ACTUAL_DELIVERY_TS BETWEEN '2016-07-20 00:00:00' AND '2016-07-31 23:59:59'

GROUP BY ld.LOAD_ID,lf.ACTUAL_DELIVERY_TS,ld.ORIG_L

如您所见,"New Column" 显示每个 Load_Id 的正确百分比,总和为 100%。现在我想按他们的频道和百分比汇总所有独特的 Load_ID。

示例:

我一直在尝试使用类似的东西:

SUM(CASE WHEN Channel = 'DA' THEN Percentage ELSE 0 END) TotalDACases,
SUM(CASE WHEN Channel = 'SS' THEN Percentage ELSE 0 END) TotalStapleCases,

或者:

SUM(CASE WHEN Channel = 'DA' THEN  CAST (CASE_QTY AS DECIMAL(38,0))/SUM(CAST(CASE_QTY AS DECIMAL(38,2))) OVER (PARTITION BY ld.LOAD_ID) END) Test,
SUM (CASE WHEN Channel = 'SS' THEN  CAST (CASE_QTY AS DECIMAL(38,0))/SUM(CAST(CASE_QTY AS DECIMAL(38,2))) OVER (PARTITION BY ld.LOAD_ID) END) Test2,

但是我收到一个错误 ("Ordered Analytical Functions can not be nested"),我认为这与我有嵌套求和函数有关。

任何想法都会很棒!