查询以列表形式返回一年中每个月的天数?
Posted
技术标签:
【中文标题】查询以列表形式返回一年中每个月的天数?【英文标题】:Query to return days in each month of the year as a list? 【发布时间】:2014-06-06 14:47:11 【问题描述】:我在网上查看过,但找不到可以返回我需要的解决方案,并希望该网站上的专家可以像您过去一样为我提供帮助。
我有一个 SQL 数据库,其中包含与建筑设备相关的带有时间戳的维护电话。
我可以查询维护信息,例如呼叫次数、平均工作时间、呼叫已打开的平均时间,并且我已按月对结果进行分组(以给出一年中的趋势)。
下一个阶段是我提供设备正常运行时间的指示。我有停机时间(为此,这是呼叫打开的时间),我可以添加一个计数来给出设备的总数。我想显示设备可用的时间百分比(正常运行时间),基于一年中每个月的小时数、项目数和通话打开的总时间。
例如
月 - 拨打电话次数 - 平均工具时间(小时) - 平均打开时间(小时) - (必需)正常运行时间
一月 - 4 - 0.37 - 1.00 - 92%
二月 - 3 - 0.83 - 35.6 - 87%
三月 - 5 - 0.50 - 1.85 - 85%
四月 - 10 - 0.72 - 119.5 - 72%
等
有人可以建议一个查询,该查询将返回我可以在现有查询中使用的每个月份的天数吗?
此外(抱歉,这里有点推)...如果在 2 月提出了一个电话,但直到 4 月才结束,我怎么能包括 3 月的停机时间?有没有办法考虑到这一点?
我在下面包含了完整的查询,我提前为格式(和质量)道歉。我应该补充一点,这是一个托管数据库,所以除了返回值之外,我不能添加表或做很多事情。
非常感谢您提供的任何帮助或指导。
下面的示例查询
`SELECT Description as 'Month',
(SELECT COUNT(TA_SEQ)
FROM F_TASKS, FASSET, FAREALO, F_CONTRACT
WHERE TA_TASK_DESC IN ('BREAKDOWN')
AND TA_FKEY_AR_SEQ = AR_SEQ
AND LO_SEQ = AR_FKEY_LO_SEQ
AND ( (LO_DESCRIPTION LIKE 'Facility%') OR ((LO_ROOM_NUMBER IN ('G.19', 'G.20')) AND (LO_DESCRIPTION LIKE '%EXIT') ) )
AND TA_FKEY_CTR_SEQ = CTR_SEQ
AND CTR_SEQ IN (100,101)
AND (TA_SHORT_DESC LIKE '%Door%' AND AR_DESCRIPTION LIKE '%DOOR%')
AND (TA_HIST_STATUS IS NULL OR TA_HIST_STATUS = 'COMPLETE')
AND TA_STATUS <> 'CANCELLED'
AND DATEPART(mm, TA_DUE_DATE)= A.Number
AND DATEPART(year, TA_DUE_DATE)= DATEPART(year, GETDATE())) AS 'No. Calls Raised',
((ISNULL((SELECT SUM(TA_TIME_TAKEN)
FROM F_TASKS, F_PPM_DETAILS, F_CONTRACT, FASSET, FAREALO
WHERE TA_TASK_DESC = 'PPM'
AND TA_FKEY_AR_SEQ = AR_SEQ
AND LO_SEQ = AR_FKEY_LO_SEQ
AND ( (LO_DESCRIPTION LIKE 'Facility%') OR (LO_ROOM_NUMBER IN ('G.19', 'G.20')) )
AND AR_DESCRIPTION LIKE '%DOOR%'
AND TA_FKEY_CTR_SEQ = CTR_SEQ
AND CTR_SEQ NOT IN (100,101)
AND PDET_FKEY_TA_SEQ = TA_SEQ
AND DATEPART(year, TA_DUE_DATE) = DATEPART(year, GETDATE())
AND DATEPART(month, TA_DUE_DATE)= A.Number ),0)) +
(ISNULL((SELECT SUM(TA_TIME_TAKEN)
FROM F_TASKS, F_BD_DETAILS, F_CONTRACT, FASSET, FAREALO
WHERE TA_TASK_DESC = 'BREAKDOWN'
AND TA_FKEY_AR_SEQ = AR_SEQ
AND LO_SEQ = AR_FKEY_LO_SEQ
AND ( (LO_DESCRIPTION LIKE 'Facility%') OR ((LO_ROOM_NUMBER IN ('G.19', 'G.20')) AND (LO_DESCRIPTION LIKE '%EXIT') ) )
AND (TA_SHORT_DESC LIKE '%Door%' AND AR_DESCRIPTION LIKE '%DOOR%')
AND TA_FKEY_CTR_SEQ = CTR_SEQ
AND CTR_SEQ IN (100,101)
AND BDET_FKEY_TA_SEQ = TA_SEQ
AND BDET_CALLER_SOURCE NOT IN ('Minor')
AND DATEPART(year, TA_DUE_DATE) = DATEPART(year, GETDATE())
AND DATEPART(month, TA_DUE_DATE)= A.Number )*1.00 /
(SELECT COUNT(TA_SEQ)
FROM F_TASKS, FASSET, FAREALO, F_CONTRACT
WHERE TA_TASK_DESC IN ('BREAKDOWN')
AND TA_FKEY_AR_SEQ = AR_SEQ
AND LO_SEQ = AR_FKEY_LO_SEQ
AND ( (LO_DESCRIPTION LIKE 'Facility%') OR ((LO_ROOM_NUMBER IN ('G.19', 'G.20')) AND (LO_DESCRIPTION LIKE '%EXIT') ) )
AND TA_FKEY_CTR_SEQ = CTR_SEQ
AND CTR_SEQ IN (100,101)
AND (TA_SHORT_DESC LIKE '%Door%' AND AR_DESCRIPTION LIKE '%DOOR%')
AND (TA_HIST_STATUS IS NULL OR TA_HIST_STATUS = 'COMPLETE')
AND TA_STATUS <> 'CANCELLED'
AND DATEPART(mm, TA_DUE_DATE)= A.Number
AND DATEPART(year, TA_DUE_DATE)= DATEPART(year, GETDATE())) ,0))) AS 'Avg Tool Time (hrs)',
ISNULL(((SELECT SUM(CASE
WHEN TA_FINISH_DATE < TA_DUE_DATE THEN DATEDIFF(hh, TA_FINISH_DATE, TA_DUE_DATE)
WHEN TA_FINISH_DATE >= TA_DUE_DATE THEN DATEDIFF(hh, TA_DUE_DATE, ISNULL(TA_FINISH_DATE,GETDATE()))
ELSE 0 END)
FROM F_TASKS, F_BD_DETAILS, F_CONTRACT, FASSET, FAREALO
WHERE TA_TASK_DESC = 'BREAKDOWN'
AND TA_FKEY_AR_SEQ = AR_SEQ
AND LO_SEQ = AR_FKEY_LO_SEQ
AND ( (LO_DESCRIPTION LIKE 'Facility%') OR ((LO_ROOM_NUMBER IN ('G.19', 'G.20')) AND (LO_DESCRIPTION LIKE '%EXIT') ) )
AND (TA_SHORT_DESC LIKE '%Door%' AND AR_DESCRIPTION LIKE '%DOOR%')
AND TA_FKEY_CTR_SEQ = CTR_SEQ
AND CTR_SEQ IN (100,101)
AND BDET_FKEY_TA_SEQ = TA_SEQ
AND BDET_CALLER_SOURCE NOT IN ('Minor','Request')
AND DATEPART(year, TA_DUE_DATE) = DATEPART(year, GETDATE())
AND DATEPART(month, TA_DUE_DATE)= A.Number)*1.00)/
(SELECT COUNT(TA_SEQ)
FROM F_TASKS, FASSET, FAREALO, F_CONTRACT
WHERE TA_TASK_DESC IN ('BREAKDOWN')
AND TA_FKEY_AR_SEQ = AR_SEQ
AND LO_SEQ = AR_FKEY_LO_SEQ
AND ( (LO_DESCRIPTION LIKE 'Facility%') OR ((LO_ROOM_NUMBER IN ('G.19', 'G.20')) AND (LO_DESCRIPTION LIKE '%EXIT') ) )
AND TA_FKEY_CTR_SEQ = CTR_SEQ
AND CTR_SEQ IN (100,101)
AND (TA_SHORT_DESC LIKE '%Door%' AND AR_DESCRIPTION LIKE '%DOOR%')
AND (TA_HIST_STATUS IS NULL OR TA_HIST_STATUS = 'COMPLETE')
AND TA_STATUS <> 'CANCELLED'
AND DATEPART(mm, TA_DUE_DATE)= A.Number
AND DATEPART(year, TA_DUE_DATE)= DATEPART(year, GETDATE())),0) AS 'Avg Time Open (hrs)'
FROM Intervals A
WHERE Type = 'Month'
ORDER BY Number`
查询结束
非常感谢 加里
【问题讨论】:
您的间隔表是什么样的? @lrb - 我不确定这个术语,抱歉 FROM Intervals A @lrb, 'A' 指的是月份数,我不认为它是一个单独的表,我认为它是 SQL 的内置函数。 您的Interval A 表中是否包含Day 信息?它是像表一样的日历吗? 【参考方案1】:您可能想检查一个月中的小时数是否应仅包含工作日的工作时间,否则,您的百分比可能会出现偏差。这适用于 sql server 2012 和 DATEFROMPARTS。您可能需要为此提出自己的功能。为简洁起见,我省略了您的大部分查询,并将您的字段设置为零。但基本概念是相似的。
SELECT
Detail.Month,
Detail.Number,
SumNoCallsMade=SUM(NoCallsRaised),
AvgAvgToolTime=AVG(AvgToolTimeHrs),
AvgAvgTimeOpen=AVG(AvgTimeOpenHrs),
HoursInMonth=MAX(HoursInMonth),
AverageUpTime=AVG(AvgToolTimeHrs) / CAST(MAX(Detail.HoursInMonth) AS DECIMAL(18,2)),
AverageOpenTime=AVG(AvgTimeOpenHrs) / CAST(MAX(Detail.HoursInMonth) AS DECIMAL(18,2))
FROM
(
SELECT
A.Month,
A.Number,
NoCallsRaised=0,
AvgToolTimeHrs=0,
AvgTimeOpenHrs=0,
HoursInMonth=(24 * DATEPART(DAY, DATEADD(DAY, -1, DATEADD(MONTH, 1, DATEFROMPARTS( DATEPART(YEAR,GETDATE()),A.Number,1)))))
FROM
Intervals A
WHERE
A.Type = 'Month'
)AS Detail
GROUP BY
Detail.Month,
Detail.Number
ORDER BY
Detail.Number
【讨论】:
非常感谢您的时间和精力,我会试一试并以任何方式回复您。以上是关于查询以列表形式返回一年中每个月的天数?的主要内容,如果未能解决你的问题,请参考以下文章