使用SQL按未知值分组

时间:2015-01-20 10:08:14

标签: sql oracle

我有一个名为“货运”的表和一个名为“订单”的表。订单和货件使用表“order_movement”相关联。因此,在最后一个表中,将有shipment_id和order_gid。 在货件表中,我有运营商的名称(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

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

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

有可能吗?谢谢

修改

我的预期输出是一个“6行”表,其中包含“IN”子句中指定的5个运营商的订单数量以及所有其他订单(具有不同运营商的订单)的数量! / p>

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

2 个答案:

答案 0 :(得分:1)

跳过in子句中的where列表,无论如何你都会阅读所有内容。而是使用案例陈述将不在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

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

答案 1 :(得分:0)

您需要手动为所有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

解码函数的作用类似于CASE语句。该函数的第一个参数是要比较的值,然后您使用成对的值,每对的第一个与第一个参数进行比较,如果匹配则返回该对的第二个。如果未找到匹配项,则末尾的额外参数为默认值。

因此,如果提供者是CNHILA.PRLG_CCPL'它会返回CNHILA.PRLG_CCPL',但如果提供者是CNHILA.IJustMadeThisUp'它将返回' OTHER'因为解码函数中给出的对都没有匹配它。

您的查询虽然不会返回从未使用过的装运方法,但您的样本结果包含计数为0的装运提供商。

可以重写此查询以获取这些结果,而您甚至不需要订单表:

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