我处于这样的情况:我需要形成一个复杂的sql来显示与datagridview in winform apps
的接口之类的日历。我已经完成了在表单中编写代码的工作。现在我想用sql在数据库级别形成日历。这是我的UI看起来像
现在我必须使用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)
首先看到我的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实现。
现在告诉我你怎么能帮助我。我还需要在这里发布什么信息。感谢
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;
答案 0 :(得分:1)
以这种方式尝试:
DECLARE @FirstOfMonth DATE={ts'2011-02-01 00:00:00'};
WITH DateBorders AS
(
SELECT @FirstOfMonth AS FirstOfMonth
,DATEADD(DAY,-1,DATEADD(MONTH,1,@FirstOfMonth)) AS LastOfMonth
)
,ThirtyOneNumbers(N) AS
(
SELECT N FROM(VALUES (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))t(N)
)
,RunningDates AS
(
SELECT N AS DayNumber
,DATEADD(DAY,N-1,DateBorders.FirstOfMonth) DayDate
FROM ThirtyOneNumbers,DateBorders
WHERE ThirtyOneNumbers.N<=DATEDIFF(DAY,DateBorders.FirstOfMonth,DateBorders.LastOfMonth) + 1
)
,RunningDatesExt AS
(
SELECT RunningDates.*
,wd.WeekDayInx
FROM RunningDates
CROSS APPLY(SELECT DATEPART(WEEKDAY,DayDate)) AS wd(WeekDayInx)
)
,HourSheetSum AS
(
SELECT hs.SpecialistID
,hs.EntryDate
,SUM(hs.HoursData) AS SumHoursData
FROM HourSheet AS hs
GROUP BY hs.SpecialistID,hs.EntryDate
)
,DataToPivot AS
(
SELECT s.SpecialistID,
s.Name,
rde.DayNumber,
CASE WHEN h.SumHoursData IS NULL THEN CASE WHEN rde.WeekDayInx IN(6,7) THEN 'S'
ELSE '8.00'
END
ELSE CAST(h.SumHoursData AS VARCHAR(100)) END AS HoursData
FROM RunningDatesExt AS rde
CROSS JOIN Specialists AS s
LEFT JOIN HourSheetSum AS h ON h.SpecialistID=s.SpecialistID AND rde.DayDate=h.EntryDate
)
SELECT pvt.*
FROM DataToPivot AS d
PIVOT
( MIN(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;