使用 SQL 按未知值分组

Group by unknown values using SQL

我有一个叫 "shipment" 的 table 和一个叫 "order" 的 table。使用 table "order_movement" 关联订单和发货。因此,在最后一个 table 中,将有 shipment_id 和 order_gid。 在货件 table 中,我有承运人的名称 (servprov_gid)。我想要做的是根据承运人的名称对所有订单进行分组。到这里为止很简单。这是我的查询:

select count(distinct order_release_gid) X,  servprov_gid Y
    from
        (select distinct ord.order_release_gid, ship.servprov_gid
        from order_release ord,
            shipment ship,
            order_movement om,
        where ship.shipment_gid = om.shipment_gid
        and om.order_release_gid = ord.order_release_gid
        and ship.servprov_gid in ('CNHILA.CAVL_CCWB','CNHILA.PRLG_CCPL','CNHILA.TCXS_CCWB','CNHILA.RDWY_CCWB', 'CNHILA.WAWL_CCWB'))
    group by servprov_gid

请忘记查询表单,这不是问题的重点。所以现在我有了某个承运人的所有订单,在该列表中选择。但现在我想知道,在同一个查询中,其他承运人的所有订单!我期望的是 table 包含

0. X     |    Y
1. 1     |    CNHILA.CAVL_CCWB
2. ...
3. 6     |    OTHER

这可能吗?谢谢

编辑

我的预期输出是“6 行”table,其中包含 "IN" 子句中指定的 5 家承运人的订单数量以及所有其他订单的数量(有不同的运营商)!

0. X     |    Y
1. 1     |    CNHILA.CAVL_CCWB
2. 2     |    CNHILA.PRLG_CCPL
3. 0     |    CNHILA.TCXS_CCWB
4. 2     |    CNHILA.RDWY_CCWB
5. 12    |    CNHILA.WAWL_CCWB
6. 6     |    OTHER

您需要手动向所有其他提供商提供相同的值,以便您可以对它们进行分组。一种方法是使用 DECODE 函数:

select 
    count(distinct order_release_gid) X,  
    ShipmentGroupID Y
from
    (select distinct 
        ord.order_release_gid, 
        decode(ship.servprov_gid,
            'CNHILA.CAVL_CCWB', 'CNHILA.CAVL_CCWB', 
            'CNHILA.PRLG_CCPL', 'CNHILA.PRLG_CCPL',
            'CNHILA.TCXS_CCWB', 'CNHILA.TCXS_CCWB',
            'CNHILA.RDWY_CCWB', 'CNHILA.RDWY_CCWB',
            'CNHILA.WAWL_CCWB', 'CNHILA.WAWL_CCWB',
            'OTHER') ShipmentGroupID
    from 
        order_release ord,
        shipment ship,
        order_movement om
    where 
        ship.shipment_gid = om.shipment_gid
        and om.order_release_gid = ord.order_release_gid
    )
group by 
        ShipmentGroupID

decode 函数的工作方式类似于 CASE 语句。函数的第一个参数是要比较的值,然后跟随着一对值,每对中的第一个与第一个参数进行比较,如果匹配则对中的第二个进行 returned .如果未找到匹配项,末尾的额外参数是默认值。

因此,如果提供商是 'CNHILA.PRLG_CCPL',它将 return 'CNHILA.PRLG_CCPL',但如果提供商是 'CNHILA.IJustMadeThisUp',它将 return 'OTHER'因为解码函数中给出的 none 对匹配它。

您的查询不会 return 从未使用过的运输方式,并且您的示例结果包含计数为 0 的运输提供商。

可以重写此查询以获得这些结果,您甚至不需要顺序 table:

select 
    count(distinct order_release_gid) X,  
    ShipmentGroupID Y
from
    (select distinct 
        om.order_release_gid, 
        decode(ship.servprov_gid,
            'CNHILA.CAVL_CCWB', 'CNHILA.CAVL_CCWB', 
            'CNHILA.PRLG_CCPL', 'CNHILA.PRLG_CCPL',
            'CNHILA.TCXS_CCWB', 'CNHILA.TCXS_CCWB',
            'CNHILA.RDWY_CCWB', 'CNHILA.RDWY_CCWB',
            'CNHILA.WAWL_CCWB', 'CNHILA.WAWL_CCWB',
            'OTHER') ShipmentGroupID
    from 
        shipment ship
        LEFT JOIN order_movement om ON ship.shipment_gid = om.shipment_gid
    )
group by 
        ShipmentGroupID

跳过 where 子句中的 in 列表,无论如何您都会阅读所有内容。而是使用 case 语句将不在 in 列表中的每个人转换为 OTHER:

select count(order_release_gid) X,  servprov_gid Y
    from
        (select distinct ord.order_release_gid,
                case
                  when ship.servprov_gid in ('CNHILA.CAVL_CCWB','CNHILA.PRLG_CCPL','CNHILA.TCXS_CCWB','CNHILA.RDWY_CCWB', 'CNHILA.WAWL_CCWB')
                  then ship.servprov_gid
                  else 'OTHER'
                end servprov_gid
        from order_release ord,
            shipment ship,
            order_movement om,
        where ship.shipment_gid = om.shipment_gid
        and om.order_release_gid = ord.order_release_gid
        )
    group by servprov_gid
    order by case servprov_gid when 'OTHER' then 2 else 1 end
           , servprov_gid

order by中的case只是为了确保OTHER行永远是最后一行。