有关在sql server

时间:2015-09-01 14:38:02

标签: c# sql-server winforms datagridview

我处于这样的情况:我需要形成一个复杂的sql来显示与datagridview in winform apps的接口之类的日历。我已经完成了在表单中编写代码的工作。现在我想用sql在数据库级别形成日历。这是我的UI看起来像

enter image description here 现在我必须使用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实现它。任何人都可以提供帮助或建议。

第二个数据透视查询是否可以更短?

感谢

修改

表结构如下

HourSheet

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;

当我执行上面的sql然后输出就像 enter image description here

现在的问题是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;

1 个答案:

答案 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;