这是问题的一个更直接的部分。以下查询有问题。它返回客户使用的每个ip_address,而不是过滤当前月份。当deallocation_date为null或者日期之间是唯一需要选择的IP地址时。这里直接下面的查询是我尝试使用相关子查询,如果它存在于这些条件计数内,并且这些IP地址的总和。但是,我在下面显示只有29个Ip地址,deallocation_date = null并且在这些日期之间取消分配,因为对于此客户,最大释放日期是八月。我知道它选择了所有已分配给客户的IP。请帮我修复子查询以返回正确的数据。我不太了解SQL,知道我的错误在哪里。我知道它与我使用的方式有关。
我也知道,因为有人指出它只会在本月最后一天的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 该月的第一天和最后一天的释放日期为null, 或者介于该月的第一天和最后一天之间的值。 如果我在下面运行第一个查询,它将返回与客户关联的错误数量的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
为了安全问题,我屏蔽了信息,但您不需要它来回答这个问题:
从第一个查询返回的值是错误的,计数是57而不是29:
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
所以我使用相关子查询编写了另一个查询来尝试仅过滤掉在该范围内分配和解除分配的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
答案 0 :(得分: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
答案 1 :(得分:0)
关于这部分:
(trunc(d.deallocation_date) between to_date(:run_date) and last_day(:run_date)
or f.deallocation_date is null))
您是否应在deallocation_date
两侧的同一张桌子中使用or
?