查询以列表形式返回一年中每个月的天数?

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

【讨论】:

非常感谢您的时间和精力,我会试一试并以任何方式回复您。

以上是关于查询以列表形式返回一年中每个月的天数?的主要内容,如果未能解决你的问题,请参考以下文章

sql 查询一个月里的数据?

sql 怎么查询最新一个月的数据

335一年中的第几天

3644一年中的第几天

使用 oracle 数据注册一年中每个月的付款

《LeetCode之每日一题》:242.一年中的第几天