如何修改我的SQL子查询以使我的查询起作用?

时间:2015-02-24 10:11:18

标签: sql database oracle

基本上,我知道SQL不允许这样做,但我希望我能做到这一点,因为这是我能想到的唯一方法来进行查询。

例如,假设有2辆送货卡车前往'55 Alaska Rd'地址。提供一些物品。

  • 1辆卡车有100台iPad和200部iPhone
  • 1辆卡车有150台iPad

我很乐意通过运行此查询来监控它们:

[select truck.truck_id,
        truck.driver_name,
        truck.current_location,
        item.prtnum,
        item.quantity
   from truck,
        box,
        item,
        shipment
  where item.box_id = box.box_id 
    and box.truck_id = truck.truck_id
    and truck.ship_adr = shipment.ship_adr 
    and shipment.ship_adr = '55 Alaska Rd.']

它告诉我我的两个人是谁,他们当前的位置,以及他们携带的是什么。它返回3行:

 | Truck ID | Driver Name | Current Location | Item Number | Item Quantity |
 |---TRK83--|---Gene R.---|------Hwy 18------|----iPad-----|------100------|
 |---TRK83--|---Gene R.---|------Hwy 18------|---iPhone----|------200------|
 |---TRK59--|---Jill M.---|------Hwy 894-----|----iPad-----|------150------|

然后我的经理打电话给我并要求我发给他同样的查询,但是经过修改后它只返回有1个项目的卡车。所以在这个例子中,他只想要返回最后一行,因为它只有iPad,而另一行有iPad和iPhone。

这就是我希望我能做到的。

[select t.truck_id,
        t.driver_name,
        t.current_location,
        i.prtnum,
        i.quantity
   from item i,
        box b,
        truck t,
        shipment s
  where i.box_id = b.box_id 
    and b.truck_id = t.truck_id
    and t.truck_id in (select tr.truck_id,
                              decode(max(it.prtnum), min(it.prtnum), max(it.prtnum), 'Mixed Items') prtnum
                         from item it,
                              box bo,
                              truck tr
                        where it.box_id = bo.box_id
                          and bo.truck_id = tr.truck_id
                          and tr.truck_id = t.truck_id
                          and prtnum != 'Mixed Items'
                     group by tr.truck_id) p
    and t.ship_adr = s.ship_adr 
    and s.ship_adr = '55 Alaska Rd.']

该子查询应该只选择父查询中没有混合部件的卡车。但这不起作用,因为:

  1. 我只能在子查询中选择“tr.truck_id”;解码也不能在那里,但我不知道还能把它放在哪里。
  2. 我不能像那样使用别名“prtnum”。
  3. 有谁知道如何实现我的假设老板要我做的事情?有没有人对我如何改变查询有任何想法,使它只选择其中有1项的卡车?我将不得不改变很多查询来做到这一点,我只是想不出一个干净的方法。甚至是一种有效的坏方法。

    感谢您阅读,谢谢您的帮助!

3 个答案:

答案 0 :(得分:0)

没有你的数据集使它有点尴尬但是,因为你只想要单个计数行,带有尾随HAVING子句的GROUP BY可以解决问题:

SELECT truck.truck_id,
        truck.driver_name,
        truck.current_location,
        item.prtnum,
        item.quantity
   FROM truck,
        box,
        item,
        shipment
  WHERE item.box_id = box.box_id 
    AND box.truck_id = truck.truck_id
    AND truck.ship_adr = shipment.ship_adr 
    AND shipment.ship_adr = '55 Alaska Rd.'
  GROUP BY truck.truck_id,
        truck.driver_name,
        truck.current_location
  HAVING COUNT(item.quantity) = 1

答案 1 :(得分:0)

您可以为每辆卡车创建一个组,然后按卡车要求他们只携带一种类型的物品。使用having子句设置组范围的条件。这是一个例子:

select  truck.truck_id
,       truck.driver_name
,       truck.current_location
,       sum(item.quantity) as sum_quantity
from    truck
join    box
on      box.truck_id = truck.truck_id
join    item
on      item.box_id = box.box_id
where   truck.ship_adr = '55 Alaska Rd.'
group by
        truck.truck_id
,       truck.driver_name
,       truck.current_location
having  count(distinct item.prtnum) = 1 -- Only one item type for this truck

不需要join shipment表。您可以使用ship_adr表中的truck来过滤地址。

我已经为每辆卡车添加了sum的所有数量,以展示除了过滤它们之外如何显示整个群组的统计数据。

答案 2 :(得分:0)

听起来像是analytic functions的工作:

with truck_info as (select truck.truck_id,
                           truck.driver_name,
                           truck.current_location,
                           item.prtnum,
                           item.quantity,
                           count(item.prtnum) over (partition by truck.truck_id, truck.driver_name, truck.current_location) cnt
                      from truck,
                           box,
                           item,
                           shipment
                     where item.box_id = box.box_id 
                       and box.truck_id = truck.truck_id
                       and truck.ship_adr = shipment.ship_adr 
                       and shipment.ship_adr = '55 Alaska Rd.')
select truck_id,
       driver_name,
       current_location,
       prtnum,
       quantity
from   truck_info
where  cnt = 1;

N.B。未测试

如果您之前从未遇到过分析功能,那么他们非常值得学习!