2014-10-27 99 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