簡體   English   中英

SQL腳本按月顯示過去的數據

[英]SQL Script to Show Past Data Month by Month

對於我的問題是否可以在其他地方回答,我深表歉意,我只是不確定要搜索什么才能知道是否在其他地方回答了我的問題。 我是SQL的新手,並且一直在嘗試查詢數據庫,該數據庫根據數據庫表中存在的百分比顯示客戶系統的正常運行時間,並將其報告為該月的平均值以及上一年度的過去表現個月。

例如,我取一個月的平均值並顯示每個月的平均值,然后根據當前月份(即3月,2月,1月等)對過去一年進行計算,總是總是過去一年的表現。

這是我當前的腳本,我必須根據客戶ID來平均一個月的工作量。...我現在想顯示每個月的過去幾年的效果:

SQL查詢:

select   cast (avg("DATA_POINT_DATA"."VALUE") as int) as "UP_VALUE",
"DATA_POINT_DATA"."UPLOAD_DATA_ID" as "CUSTOMER_ID"
 from   "DB_TABLE"."DATA_POINT_DATA" "DATA_POINT_DATA",
    "DB_TABLE"."CALC_DATA" "CALC_DATA" 
 where   "DATA_POINT_DATA"."CALC_DATA_ID"="DATA_POINT_DATA"."ID"
  and    "CALC_DATA"."NAME" ='CustomerUp' 
   and   "DATA_POINT_DATA"."UPLOAD_DATA_ID" in ('123abc')
   and  "UPLOAD_TIME" between ('01-FEB-17') and ('28-FEB-17') 
   group by "DATA_POINT_DATA"."UPLOAD_DATA_ID";

查詢輸出:

UP_VALUE    CUSTOMER_ID
-------- --------------
     100         123abc

預期產量:

MONTH    UP_VALUE    CUSTOMER_ID
----- ----------- --------------
FEB           100         123abc
JAN           100         123abc
DEC           100         123abc
NOV            90         123abc
OCT           100         123abc
SEP           100         123abc
AUG           100         123abc
JUL            89         123abc
JUN           100         123abc
MAY            75         123abc
APR           100         123abc
MAR           100         123abc
FEB            90         123abc

您只需要添加月份即可選擇和分組:

SELECT datepart(upload_time, DP_MONTH) as upload_month, Cast (Avg("data_point_data"."value") AS INT) AS "UP_VALUE", 
       "data_point_data"."upload_data_id" AS "CUSTOMER_ID" 
FROM   "DB_TABLE"."data_point_data" "DATA_POINT_DATA", 
       "DB_TABLE"."calc_data" "CALC_DATA" 
WHERE  "data_point_data"."calc_data_id" = "data_point_data"."id" 
       AND "calc_data"."name" = 'CustomerUp' 
       AND "data_point_data"."upload_data_id" IN ( '123abc' ) 
       AND "upload_time" BETWEEN ( '01-FEB-17' ) AND ( '28-FEB-17' ) 
GROUP  BY datepart(upload_time, DP_MONTH), "data_point_data"."upload_data_id"; 

您有一個匯總avg()函數調用,並且已經按選擇列表中的非匯總列進行分組。 要獲取上一年的每個月(直到上個月末)的數據,您只需要在選擇列表和group-by子句中包括月份即可:

select to_char(trunc("UPLOAD_TIME", 'MM'), 'MON') as "MONTH",
  cast (avg("DATA_POINT_DATA"."VALUE") as int) as "UP_VALUE",
  "DATA_POINT_DATA"."UPLOAD_DATA_ID" as "CUSTOMER_ID"
from "DB_TABLE"."DATA_POINT_DATA" "DATA_POINT_DATA",
  "DB_TABLE"."CALC_DATA" "CALC_DATA" 
where "DATA_POINT_DATA"."CALC_DATA_ID"="DATA_POINT_DATA"."ID"
and "CALC_DATA"."NAME" ='CustomerUp' 
and "DATA_POINT_DATA"."UPLOAD_DATA_ID" in ('123abc')
and "UPLOAD_TIME" between ('01-MAR-16') and ('28-FEB-17') 
group by trunc("UPLOAD_TIME", 'MM'), "DATA_POINT_DATA"."UPLOAD_DATA_ID";

表達式trunc("UPLOAD_TIME", 'MM')為您提供該列值在月份的第一天午夜。 這可以用於分組依據,因此一個月中的所有日期都被視為同一天,即第一天。 然后,可以在選擇列表中將相同的表達式轉換為僅顯示月份名稱的字符串。 (我假設您的會話是英語,但是to_char()有第三個參數來處理 )。

where "DATA_POINT_DATA"."CALC_DATA_ID"="DATA_POINT_DATA"."ID"

看起來很奇怪,目前您似乎在兩個表之間沒有任何實際的連接條件; 我懷疑應該是:

where "DATA_POINT_DATA"."CALC_DATA_ID"="CALC_DATA"."ID"

但也許不是。

執行以下操作時,您將依賴會話NLS設置:

and  "UPLOAD_TIME" between ('01-FEB-17') and ('28-FEB-17') 

您應該使用顯式的to_date()調用和格式掩碼,並且最好不要假定會話語言是英語(這會影響月份名稱的處理),但至少要這樣做:

and  "UPLOAD_TIME" between to_date('01-FEB-17', 'DD-MON-RR')
  and to_date('28-FEB-17', 'DD-MON-RR') 

...但是即使在這里,也可以使用4位數字的年份,如果您的任何列值在午夜之后都有時間,那么您將丟失諸如2017-02-28 00:00:01類的數據。

您也不需要在所有對象名稱周圍使用雙引號; 沒有它們,對象名稱的大小寫就無關緊要,這可能會使它更容易閱讀。 您還應該使用ANSI連接語法。 假設上面的子句觀察正確,則可以執行以下操作:

select to_char(trunc(upload_time, 'MM'), 'MON') as month,
  cast (avg(data_point_data.value) as int) as up_value,
  data_point_data.upload_data_id as customer_id
from db_table.data_point_data
join db_table.calc_data
on data_point_data.calc_data_id=calc_data.id
where calc_data.name ='CustomerUp' 
and data_point_data.upload_data_id = '123abc'
and upload_time >= add_months(trunc(sysdate, 'MM'), -12)
and upload_time < trunc(sysdate, 'MM')
group by trunc(upload_time, 'MM'), data_point_data.upload_data_id
order by trunc(upload_time, 'MM') desc;

對於日期范圍,我將其基於當前日期,並使用>=<而不是between來避免非午夜時間出現問題。 您可以看到這些表達式求和的值:

select to_char(add_months(trunc(sysdate, 'MM'), -12), 'YYYY-MM-DD HH24:MI:SS') as from_time,
  to_char(trunc(sysdate, 'MM'), 'YYYY-MM-DD HH24:MI:SS') as to_time
from dual;

FROM_TIME           TO_TIME            
------------------- -------------------
2016-03-01 00:00:00 2017-03-01 00:00:00

最后, cast(... as int)有點不尋常; 根據您希望如何處理小數部分,還可以查看trunc()ceil()floor()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM