【发布时间】:2015-09-01 14:38:01
【问题描述】:
我处于需要形成一个复杂的 sql 以显示与 datagridview in winform apps 类似的界面的情况。我已经完成了以表格形式编写代码的工作。现在我想用 sql 在数据库级别形成日历。这是我的用户界面的样子
现在我必须使用 sql 在数据库级别生成上述输出。在这里,我给出了下面的 sql,它几乎给出了正确的数据,但仍然存在一个小问题。先看sql
DECLARE @MonthNo INT
DECLARE @Year INT
SET @MonthNo = 1
SET @Year = 2011
;WITH DataToPivot AS
( SELECT s.SpecialistID,
s.Name,
DayNumber = DATEPART(DAY, h.EntryDate),
HoursData = CASE WHEN DATEPART(WEEKDAY, h.EntryDate) IN (6, 7) THEN CONVERT(VARCHAR(10), 'S')
WHEN h.HoursData IS NULL THEN '8.00'
ELSE h.HoursData
END
FROM Specialists AS s
LEFT JOIN HourSheet AS h
ON h.SpecialistID = s.SpecialistID
AND Month(h.EntryDate)= @MonthNo
AND Year(h.EntryDate) = @Year
WHERE s.IsActive = 1
AND s.IsSpecialist = 1
AND s.IsExcluded = 0
)
select * from DataToPivot
SELECT pvt.SpecialistID,
pvt.Name,
[1] = ISNULL(pvt.[1], '8.00'),
[2] = ISNULL(pvt.[2], '8.00'),
[3] = ISNULL(pvt.[3], '8.00'),
[4] = ISNULL(pvt.[4], '8.00'),
[5] = ISNULL(pvt.[5], '8.00'),
[6] = ISNULL(pvt.[6], '8.00'),
[7] = ISNULL(pvt.[7], '8.00'),
[8] = ISNULL(pvt.[8], '8.00'),
[9] = ISNULL(pvt.[9], '8.00'),
[10] = ISNULL(pvt.[10], '8.00'),
[11] = ISNULL(pvt.[11], '8.00'),
[12] = ISNULL(pvt.[12], '8.00'),
[13] = ISNULL(pvt.[13], '8.00'),
[14] = ISNULL(pvt.[14], '8.00'),
[15] = ISNULL(pvt.[15], '8.00'),
[16] = ISNULL(pvt.[16], '8.00'),
[17] = ISNULL(pvt.[17], '8.00'),
[18] = ISNULL(pvt.[18], '8.00'),
[19] = ISNULL(pvt.[19], '8.00'),
[20] = ISNULL(pvt.[20], '8.00'),
[21] = ISNULL(pvt.[21], '8.00'),
[22] = ISNULL(pvt.[22], '8.00'),
[23] = ISNULL(pvt.[23], '8.00'),
[24] = ISNULL(pvt.[24], '8.00'),
[25] = ISNULL(pvt.[25], '8.00'),
[26] = ISNULL(pvt.[26], '8.00'),
[27] = ISNULL(pvt.[27], '8.00'),
[28] = ISNULL(pvt.[28], '8.00'),
[29] = ISNULL(pvt.[29], '8.00'),
[30] = ISNULL(pvt.[30], '8.00'),
[31] = ISNULL(pvt.[31], '8.00')
FROM DataToPivot AS d
PIVOT
( SUM(HoursData)
FOR DayNumber IN
( [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11],
[12], [13], [14], [15], [16], [17], [18], [19], [20], [21],
[22], [23], [24], [25], [26], [27], [28], [29], [30], [31]
)
) AS pvt
ORDER BY pvt.SpecialistID;
如果HoursData day 为空,如果日期为sunday or saturday,那么我需要显示S,如果日期不是sunday or saturday 但 HoursData 为空,那么我必须显示8:00 否则我需要显示值存储在HoursData。
如何使用pivot sql 实现它。任何人都可以提供帮助或提出任何建议。
是否有可能第二个透视查询可以更短?
谢谢
编辑
表结构如下
工时表
SpecialistID INT
EntryDate DATETIME
HoursData decimal
专家
SpecialistID INT
Name varchar(50)
编辑 1
首先查看我的 sql,它与我想要的很接近,但仍需要一些更改
DECLARE @MonthNo INT
DECLARE @Year INT
SET @MonthNo = 1
SET @Year = 2011
;WITH DataToPivot AS
( SELECT s.SpecialistID,
s.Name,
DayNumber = DATEPART(DAY, h.EntryDate),
HoursData = CASE WHEN DATEPART(WEEKDAY, h.EntryDate) IN (6, 7) THEN CONVERT(VARCHAR(10), 'S')
WHEN h.HoursData IS NULL THEN '8.00'
ELSE h.HoursData
END
FROM Specialists AS s
LEFT JOIN HourSheet AS h
ON h.SpecialistID = s.SpecialistID
AND Month(h.EntryDate)= @MonthNo
AND Year(h.EntryDate) = @Year
WHERE s.IsActive = 1
AND s.IsSpecialist = 1
AND s.IsExcluded = 0
)
SELECT pvt.SpecialistID,
pvt.Name,
[1] = ISNULL(pvt.[1], '8.00'),
[2] = ISNULL(pvt.[2], '8.00'),
[3] = ISNULL(pvt.[3], '8.00'),
[4] = ISNULL(pvt.[4], '8.00'),
[5] = ISNULL(pvt.[5], '8.00'),
[6] = ISNULL(pvt.[6], '8.00'),
[7] = ISNULL(pvt.[7], '8.00'),
[8] = ISNULL(pvt.[8], '8.00'),
[9] = ISNULL(pvt.[9], '8.00'),
[10] = ISNULL(pvt.[10], '8.00'),
[11] = ISNULL(pvt.[11], '8.00'),
[12] = ISNULL(pvt.[12], '8.00'),
[13] = ISNULL(pvt.[13], '8.00'),
[14] = ISNULL(pvt.[14], '8.00'),
[15] = ISNULL(pvt.[15], '8.00'),
[16] = ISNULL(pvt.[16], '8.00'),
[17] = ISNULL(pvt.[17], '8.00'),
[18] = ISNULL(pvt.[18], '8.00'),
[19] = ISNULL(pvt.[19], '8.00'),
[20] = ISNULL(pvt.[20], '8.00'),
[21] = ISNULL(pvt.[21], '8.00'),
[22] = ISNULL(pvt.[22], '8.00'),
[23] = ISNULL(pvt.[23], '8.00'),
[24] = ISNULL(pvt.[24], '8.00'),
[25] = ISNULL(pvt.[25], '8.00'),
[26] = ISNULL(pvt.[26], '8.00'),
[27] = ISNULL(pvt.[27], '8.00'),
[28] = ISNULL(pvt.[28], '8.00'),
[29] = ISNULL(pvt.[29], '8.00'),
[30] = ISNULL(pvt.[30], '8.00'),
[31] = ISNULL(pvt.[31], '8.00')
FROM DataToPivot AS d
PIVOT
( SUM(HoursData)
FOR DayNumber IN
( [1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11],
[12], [13], [14], [15], [16], [17], [18], [19], [20], [21],
[22], [23], [24], [25], [26], [27], [28], [29], [30], [31]
)
) AS pvt
ORDER BY pvt.SpecialistID;
现在的问题是看到 Sarah Rodham 第一列,第二列显示 8.00,即星期日或星期六。所以首先我需要检查小时表中是否存在日期 1/JAN/2011 的数据,然后我将显示如果没有找到数据,那么我将检查日期是否与太阳或星期六有关.....如果是然后如果日期不是太阳或星期六,我将显示“S”,然后我将显示 8.00,这是我无法通过上述 sql 实现的。
现在告诉我你能如何帮助我。我还需要在这里发布什么信息。谢谢
编辑 2
DECLARE @Days AS INT
DECLARE @DateInput AS VARCHAR(10)
SET @DateInput = '01/01/2011'
SELECT @Days = DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@DateInput),0)))
PRINT @Days
;WITH TotalDaysInMoth(MonthNumber) AS
(
SELECT 1
UNION ALL
SELECT MonthNumber+1
FROM TotalDaysInMoth
WHERE MonthNumber < @Days
)
select * from TotalDaysInMoth;
【问题讨论】:
-
请提供专家和小时表的结构以及一些测试数据行...
-
我用您要求的表格结构更新了我的帖子。如果可能,请查看并回答。
-
请添加一些示例数据和预期输出。几行就足够了...
-
还有一点:SQL Server 的哪个版本?
标签: c# sql-server winforms datagridview