2014-10-27 91 views
0

下面是问题的一个更直接的部分。以下查询有问题。它返回客户曾经使用过的每个ip_address,而不是过滤当前月份的ip_address。当deallocation_date为空或日期之间是唯一需要选择的IP地址时。这里直接查询的是我试图做一个相关的子查询使用,如果它存在于这些条件计数,总和为这些IP地址。然而,下面我显示,只有29个IP地址deallocation_date = null,并在这些日期之间释放,因为对于该客户,最大释放日期是在8月。我知道它选择了所有分配给客户的IP。请帮我修复子查询以返回正确的数据。我用SQL知道自己的错误在哪里并不是那么棒。我知道这与我使用或使用的方式有关。复杂的Oracle查询不会返回正确的信息

我也知道,因为有人指出,它只会选择直到本月最后一天的00:00:00,现在我确定我可以稍后再解决。我需要它来返回正确的数据。据我所知,这个客户本月没有解除分配。

麻烦的部分是:

和(TRUNC(d.deallocation_date)TO_DATE(间:run_date)和LAST_DAY(:run_date)或f.deallocation_date为null))

因为应该过滤无论ip_address_usages表中的内容为多少,IP的值都为29,但计数停留在57,这意味着它将它们全部选中。

set pagesize 2000 
set linesize 300 
break on report on customer_name skip 1 
compute sum label Total of GigaBytes_Sent GigaBytes_Received IPS_IN_USE on customer_name 
compute sum label Grand-Total of GigaBytes_Sent GigaBytes_Received IPS_IN_USE on REPORT 
column GigaBytes_Sent format 999,999,999,999.99 
column GigaBytes_Received format 999,999,999,999.99 

select customer_name, 
     substr(decode(vcd_managed,'Y',vm_name,'N',vm_group_name || ' ' || vm_display_name),1,100) vm_name, 
     decode(vcd_managed,'Y',null,'N',vm_display_name) vm_display_name, 
     sum(bytes_sent)*1.8/power(10,9) GigaBytes_Sent, 
     sum(bytes_received)*1.8/power(10,9) GigaBytes_Received, 
     count(unique e.ip_address_id) IPS_IN_USE 
    from customers a, 
     vm_groups b, 
     vms c, 
     vm_ip_address_histories d, 
     ip_address_usages e 
where a.customer_id = b.customer_id 
    and b.vm_group_id=c.vm_group_id 
    and c.vm_id=d.vm_id 
    and d.ip_address_id=e.ip_address_id 
    and trunc(e.datetime) between :run_date and last_day(:run_date) 
    and exists (select f.deallocation_date 
        from vm_ip_address_histories f 
        where f.vm_id = d.vm_id 
        and (trunc(d.deallocation_date) between to_date(:run_date) and last_day(:run_date) or f.deallocation_date is null)) 
    and inactive = 'N' 
    and a.customer_id = 30 
-- and (bytes_sent > 0 or bytes_received > 0) 
group by customer_name, 
     substr(decode(vcd_managed,'Y',vm_name,'N',vm_group_name || ' ' || vm_display_name),1,100), 
     decode(vcd_managed,'Y',null,'N',vm_display_name) 
order by 1,2,3 
/

我试图总结从ip_address_usages表发送和收到的字节, 同时计数属于 之间的客户有空的释放日期的月份的第一天和最后一天的不同ip_address_id的, 或该月的第一天和最后一天之间的值。 当我运行下面的第一个查询时,它将返回与客户关联的IP地址数量错误。

我明显可以看到它没有考虑本月的最后一天和第一天, 但是当我补充说它抛出了总结,如下所示。 我正在努力使汇总和IP帐户是正确的。

这里是表格关系,我只列出了相关的描述。

Customers > VM_Groups 
    VM_Groups > VMS 
    VMS > VM_IP_ADDRESS_HISTORIES 
    VM_IP_ADDRESS_HISTORIES > IP_ADDRESSES by ip_address_id, 
    IP_ADDRESSES > IP_ADDRESS_USAGES "this is where bytes sent and received is" relates to IP_ADDRESSES by ip_address_id 

我屏蔽了安全问题的信息,但你并不需要它来回答这个问题:

variable run_date varchar2(30) 
    exec :run_date := to_date('1-oct-14') 

    set pagesize 2000 
    set linesize 300 
    break on report on customer_name skip 1 
    compute sum label Total of GigaBytes_Sent GigaBytes_Received IPS_IN_USE on customer_name 
    compute sum label Grand-Total of GigaBytes_Sent GigaBytes_Received IPS_IN_USE on REPORT 
    column GigaBytes_Sent format 999,999,999,999.99 
    column GigaBytes_Received format 999,999,999,999.99 

    select customer_name, 
      substr(decode(vcd_managed,'Y',vm_name,'N',vm_group_name || ' ' || vm_display_name),1,100) vm_name, 
      decode(vcd_managed,'Y',null,'N',vm_display_name) vm_display_name, 
      sum(bytes_sent)*1.8/power(10,9) GigaBytes_Sent, 
      sum(bytes_received)*1.8/power(10,9) GigaBytes_Received, 
      count(unique e.ip_address_id) IPS_IN_USE 
     from customers a, 
      vm_groups b, 
      vms c, 
      vm_ip_address_histories d, 
      ip_address_usages e 
    where a.customer_id = b.customer_id 
     and b.vm_group_id=c.vm_group_id 
     and c.vm_id=d.vm_id 
     and d.ip_address_id=e.ip_address_id 
     and trunc(e.datetime) between :run_date and last_day(:run_date) 
     and inactive = 'N' 
     and a.customer_id = 30 
    -- and (bytes_sent > 0 or bytes_received > 0) 
    group by customer_name, 
      substr(decode(vcd_managed,'Y',vm_name,'N',vm_group_name || ' ' || vm_display_name),1,100), 
      decode(vcd_managed,'Y',null,'N',vm_display_name) 
    order by 1,2,3 
    /


    CUSTOMER_NAME    VM_NAME             VM_DISPLAY_NAME   GIGABYTES_SENT GIGABYTES_RECEIVED IPS_IN_USE 
    ------------------------------ ---------------------------------------------------------------------------------------------------- ------------------------------ ------------------- ------------------- ---------- 
    mask/masked  mask/masked                     198.59     168.57   29 
         mask/masked                     43.35      33.95   19 
         mask/masked                     164.04     135.86    9 
    ***************************************************************************************************************************************************************************************************  
    Total                      405.98     338.38   57 

    set pagesize 2000 
    set linesize 300 
    break on report on customer_name skip 1 
    compute sum label Total of GigaBytes_Sent GigaBytes_Received IPS_IN_USE on customer_name 
    compute sum label Grand-Total of GigaBytes_Sent GigaBytes_Received IPS_IN_USE on REPORT 
    column GigaBytes_Sent format 999,999,999,999.99 
    column GigaBytes_Received format 999,999,999,999.99 

    select customer_name, 
      substr(decode(vcd_managed,'Y',vm_name,'N',vm_group_name || ' ' || vm_display_name),1,100) vm_name, 
      decode(vcd_managed,'Y',null,'N',vm_display_name) vm_display_name, 
      sum(bytes_sent)*1.8/power(10,9) GigaBytes_Sent, 
      sum(bytes_received)*1.8/power(10,9) GigaBytes_Received, 
      count(unique e.ip_address_id) IPS_IN_USE 
     from customers a, 
      vm_groups b, 
      vms c, 
      vm_ip_address_histories d, 
      ip_address_usages e 
    where a.customer_id = b.customer_id 
     and b.vm_group_id=c.vm_group_id 
     and c.vm_id=d.vm_id 
     and d.ip_address_id=e.ip_address_id 
     and trunc(e.datetime) between :run_date and last_day(:run_date) 
     and (d.deallocation_date is null or d.deallocation_date between to_date(:run_date) and last_day(:run_date)) 
     and inactive = 'N' 
     and a.customer_id =30 
    -- and (bytes_sent > 0 or bytes_received > 0) 
    group by customer_name, 
      substr(decode(vcd_managed,'Y',vm_name,'N',vm_group_name || ' ' || vm_display_name),1,100), 
      decode(vcd_managed,'Y',null,'N',vm_display_name) 
    order by 1,2,3 
    /

    CUSTOMER_NAME    VM_NAME             VM_DISPLAY_NAME   GIGABYTES_SENT GIGABYTES_RECEIVED IPS_IN_USE 
    ------------------------------ ---------------------------------------------------------------------------------------------------- ------------------------------ ------------------- ------------------- ---------- 
    mask/masked  mask/masked                     .00       .01    8 
         mask/masked                     43.35      33.95    18 
         mask/masked                     .00       .01    3 
    ***************************************************************************************************************************************************************************************************                 
    Total                      43.35      33.97   29 

    select max(deallocation_date) 
    from vm_ip_address_histories a, 
    vms b, vm_groups c, 
    customers d 
    where a.vm_id = b.vm_id 
    and b.vm_group_id = c.vm_group_id 
    and c.customer_id = d.customer_id 
    and d.customer_id = 30 
    /

    MAX(DEALLOCATION_DATE) 
    --------------------------------------------------------------------------- 
    04-AUG-14 06.04.30.000000 PM 


    select distinct e.ip_address, 
    a.customer_name, 
    c.vm_id, 
    d.allocation_date, 
    d.deallocation_date 
    from customers a, 
    vm_groups b, 
    vms c, 
    vm_ip_address_histories d, 
    ip_addresses e 
    where a.customer_id=30 
    and a.customer_id = b.customer_id 
    and b.vm_group_id = c.vm_group_id 
    and c.vm_id = d.vm_id 
    and d.ip_address_id = e.ip_address_id 
    and exists (select * from vm_ip_address_histories where d.deallocation_date is null or trunc(d.deallocation_date) >= to_date('1-oct-14')) 
    /

     2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 
    IP_ADDRESS   CUSTOMER_NAME    VM_ID ALLOCATION_DATE         DEALLOCATION_DATE 
    -------------------------------- ------------------------------ ---------- --------------------------------------------------------------------------- --------------------------------------------------------------------------- 
    XXXXXXXX    XXXXXXXXX    27374 17-JUN-14 03.58.48.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 30-JUL-14 03.18.41.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 17-JUN-14 04.43.48.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 17-JUN-14 03.43.48.000000 PM 
    XXXXXXXX    XXXXXXXXX     365 17-JAN-14 03.02.25.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 17-JUN-14 03.43.48.000000 PM 
    XXXXXXXX    XXXXXXXXX    1586 26-FEB-14 10.48.18.000000 AM 
    XXXXXXXX    XXXXXXXXX     365 17-JAN-14 03.02.25.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 28-JUN-14 12.45.22.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 21-JUN-14 01.29.23.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 17-JUN-14 04.58.48.000000 PM 

    IP_ADDRESS   CUSTOMER_NAME    VM_ID ALLOCATION_DATE         DEALLOCATION_DATE 
    -------------------------------- ------------------------------ ---------- --------------------------------------------------------------------------- --------------------------------------------------------------------------- 
    XXXXXXXX    XXXXXXXXX     365 17-JAN-14 03.02.25.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 17-JUN-14 03.58.48.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 17-JUN-14 03.43.48.000000 PM 
    XXXXXXXX    XXXXXXXXX     365 17-JAN-14 03.02.25.000000 PM 
    XXXXXXXX    XXXXXXXXX     365 20-FEB-14 04.47.33.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 17-JUN-14 04.13.48.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 17-JUN-14 03.58.48.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 17-JUN-14 04.43.48.000000 PM 
    XXXXXXXX    XXXXXXXXX    1586 17-JUN-14 02.13.47.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 04-AUG-14 06.04.30.000000 PM 
    XXXXXXXX    XXXXXXXXX    1586 25-FEB-14 05.03.12.000000 PM 

    IP_ADDRESS   CUSTOMER_NAME    VM_ID ALLOCATION_DATE         DEALLOCATION_DATE 
    -------------------------------- ------------------------------ ---------- ---------------------------select customer_name, 
     substr(decode(vcd_managed,'Y',vm_name,'N',vm_group_name || ' ' || vm_display_name),1,100) vm_name, 
     decode(vcd_managed,'Y',null,'N',vm_display_name) vm_display_name, 
     sum(bytes_sent)*1.8/power(10,9) GigaBytes_Sent, 
     sum(bytes_received)*1.8/power(10,9) GigaBytes_Received, 
     count(unique e.ip_address_id) IPS_IN_USE 
    from customers a, 
     vm_groups b, 
     vms c, 
     vm_ip_address_histories d, 
     ip_address_usages e 
where a.customer_id = b.customer_id 
    and b.vm_group_id=c.vm_group_id 
    and c.vm_id=d.vm_id 
    and d.ip_address_id=e.ip_address_id 
    and trunc(e.datetime) between :run_date and last_day(:run_date) 
    and exists (select * from vm_ip_address_histories f where deallocation_date is null or trunc(deallocation_date) between :run_date and last_day(:run_date)) 
    and inactive = 'N' 
    and a.customer_id = 30 
-- and (bytes_sent > 0 or bytes_received > 0) 
group by customer_name, 
     substr(decode(vcd_managed,'Y',vm_name,'N',vm_group_name || ' ' || vm_display_name),1,100), 
     decode(vcd_managed,'Y',null,'N',vm_display_name) 
order by 1,2,3 
------------------------------------------------ --------------------------------------------------------------------------- 
    XXXXXXXX    XXXXXXXXX     365 17-JAN-14 03.02.25.000000 PM 
    XXXXXXXX    XXXXXXXXX     365 17-JAN-14 03.02.25.000000 PM 
    XXXXXXXX    XXXXXXXXX     365 17-JAN-14 03.02.25.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 17-JUN-14 04.13.48.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 17-JUN-14 03.43.48.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 28-JUN-14 12.30.23.000000 PM 
    XXXXXXXX    XXXXXXXXX    27374 17-JUN-14 04.43.48.000000 PM 

    29 rows selected. 




    select distinct e.ip_address 
    from customers a, 
    vm_groups b, 
    vms c, 
    vm_ip_address_histories d, 
    ip_addresses e 
    where a.customer_id=30 
    and a.customer_id = b.customer_id 
    and b.vm_group_id = c.vm_group_id 
    and c.vm_id = d.vm_id 
    and d.ip_address_id = e.ip_address_id 
    and (d.deallocation_date is null or d.deallocation_date between to_date('01-10-2014', 'DD-MM-YYYY') and to_date('31-10-2014 23:59:59', 'DD-MM-YYYY HH24:MI:SS')) 
    / 

    IP_ADDRESS 
    -------------------------------- 
    MASKED FOR SECURITY 

    29 rows selected. 



    select count(distinct e.ip_address) 
    from customers a, 
    vm_groups b, 
    vms c, 
    vm_ip_address_histories d, 
    ip_addresses e 
    where a.customer_id=30 
    and a.customer_id = b.customer_id 
    and b.vm_group_id = c.vm_group_id 
    and c.vm_id = d.vm_id 
    and d.ip_address_id = e.ip_address_id 
    and (d.deallocation_date is null or d.deallocation_date between to_date('01-10-2014', 'DD-MM-YYYY') and to_date('31-10-2014 23:59:59', 'DD-MM-YYYY HH24:MI:SS')) 
    /

    COUNT(DISTINCTE.IP_ADDRESS) 
    --------------------------- 
       29 

从,这是错误的次数为57,而不是29的第一个查询返回的值

所以我写了另一个查询使用相关的子查询来尝试和过滤只有IP的范围内分配和释放,但它仍然返回57,但正确的使用情况数据。现在显然只有29个,因为我已经充分展现了以上。因此,它在我的查询中。请看看并告诉我这个查询有什么问题。

select customer_name, 
      substr(decode(vcd_managed,'Y',vm_name,'N',vm_group_name || ' ' || vm_display_name),1,100) vm_name, 
      decode(vcd_managed,'Y',null,'N',vm_display_name) vm_display_name, 
      sum(bytes_sent)*1.8/power(10,9) GigaBytes_Sent, 
      sum(bytes_received)*1.8/power(10,9) GigaBytes_Received, 
      count(unique e.ip_address_id) IPS_IN_USE 
     from customers a, 
      vm_groups b, 
      vms c, 
      vm_ip_address_histories d, 
      ip_address_usages e 
    where a.customer_id = b.customer_id 
     and b.vm_group_id=c.vm_group_id 
     and c.vm_id=d.vm_id 
     and d.ip_address_id=e.ip_address_id 
     and trunc(e.datetime) between :run_date and last_day(:run_date) 
     and exists (select * from vm_ip_address_histories f where deallocation_date is null or trunc(deallocation_date) between :run_date and last_day(:run_date)) 
     and inactive = 'N' 
     and a.customer_id = 30 
    -- and (bytes_sent > 0 or bytes_received > 0) 
    group by customer_name, 
      substr(decode(vcd_managed,'Y',vm_name,'N',vm_group_name || ' ' || vm_display_name),1,100), 
      decode(vcd_managed,'Y',null,'N',vm_display_name) 
    order by 1,2,3 

基本上与此查询我希望它只是总结,当它的相关子查询

同样的事情在这里的范围内,存在数

select customer_name, 
     substr(decode(vcd_managed,'Y',vm_name,'N',vm_group_name || ' ' || vm_display_name),1,100) vm_name, 
     decode(vcd_managed,'Y',null,'N',vm_display_name) vm_display_name, 
     sum(bytes_sent)*1.8/power(10,9) GigaBytes_Sent, 
     sum(bytes_received)*1.8/power(10,9) GigaBytes_Received, 
     count(unique e.ip_address_id) IPS_IN_USE 
    from customers a, 
     vm_groups b, 
     vms c, 
     vm_ip_address_histories d, 
     ip_address_usages e 
where a.customer_id = b.customer_id 
    and b.vm_group_id=c.vm_group_id 
    and c.vm_id=d.vm_id 
    and d.ip_address_id=e.ip_address_id 
    and trunc(e.datetime) between :run_date and last_day(:run_date) 
    and exists (select f.deallocation_date from vm_ip_address_histories f where f.vm_id = d.vm_id and (f.deallocation_date is null or trunc(f.deallocation_date) between :run_date and last_day(:run_date))) 
    and inactive = 'N' 
    and a.customer_id = 30 
-- and (bytes_sent > 0 or bytes_received > 0) 
group by customer_name, 
     substr(decode(vcd_managed,'Y',vm_name,'N',vm_group_name || ' ' || vm_display_name),1,100), 
     decode(vcd_managed,'Y',null,'N',vm_display_name) 
order by 1,2,3 
+1

你能否把一个可重复的测试案例(即我们可以在系统中创建你所需要的表,填充一些虚拟的数据,并显示出我们预期的结果运行的东西)?否则,其他人几乎不可能猜测问题出在哪里。 – 2014-10-27 23:01:24

+0

如果我能抽出时间去做,我会在今晚做。感谢您花时间看看。这就是为什么我包括这么多的数据是希望有人能看到什么即时通讯没有看到,或者调整我的查询。基本上它查看了vm_ip_address_histories表中的所有ip并忽略了释放日期,但是当我将它设置为查看它抛出我的使用情况数据时,我预计它会减少一点,因为它不会将坏IP与客户相关联但到目前为止,我就知道它错了。\ – 2014-10-27 23:05:34

+0

林多加入一些数据现在可能的帮助。 – 2014-10-27 23:06:06

回答

0

的LAST_DAY函数返回的日期该月的最后一天作为输入提供,但它也包括你提供的日期的时间部分,所以你的第

d.deallocation_date between to_date(:run_date) and last_day(:run_date)) 

大概应该是

truncate(d.deallocation_date) between to_date(:run_date) and last_day(:run_date)) 

您的代码集:run_date为varchar场没有时间组件,所以LAST_DAY(:run_date)将是00:00:00,所以如果d.deallocation_date有时间晚于此时,它不会被选中。

SQL> variable run_date varchar2(30) 
SQL> exec :run_date := to_date('1-oct-14') 

SQL> select to_char(to_date(:run_date), 'yyyy-mm-dd hh24:mi:ss') as first_of_month, 
2*  to_char(last_day(to_date(:run_date)), 'yyyy-mm-dd hh24:mi:ss') as last_of_month from dual; 

FIRST_OF_MONTH  LAST_OF_MONTH 
------------------- ------------------- 
2014-10-01 00:00:00 2014-10-31 00:00:00 
+0

我看到,但有什么毛病我的查询,它实际上不是过滤释放日期它只是不断选择所有 – 2014-10-27 23:58:46

+0

能否请你看问题的顶部,现在,只是帮助我的子查询@马克·斯图尔特 – 2014-10-28 00:05:46

+0

啊,好的,对不起,@Grant。我现在也很难过! – 2014-10-28 00:18:48

0

至于这一部分:

(trunc(d.deallocation_date) between to_date(:run_date) and last_day(:run_date) 
or f.deallocation_date is null)) 

如果您要在or两侧使用deallocation_date来自同一个表?

+0

嗯,我试图找到它是否有日期的空间,或者如果释放日期。 – 2014-10-28 14:47:03