0

用户正在从 .aspx 页面将数据输入到我的“跟踪”表中。他们正在为不同的活动输入一系列日期,如果他们想被提醒该日期,请选中一个框。我目前遇到的具体问题是限制我的 IN 语句中的列:

SELECT [id], [name], MIN([DATE]) AS [MinDate] 
FROM track UNPIVOT ([DATE] FOR d IN ([date1],[date2],[date2])) unpvt
GROUP BY [id], [name]

date1如果 columndate1chk的值为,我只想包括1。同样,date2如果date2chk为“1”等。否则该date#列不包含在 IN 中。

在此之后,我的挑战是能够更新表,例如,例如,如果是最小值,则为特定记录date2chk设置从1到。0date2

非常感谢您的想法——事实证明这是我处理过的更难的问题之一。

编辑(感谢您的反馈):

数据

ID       Date1       Date1Chk         Date2      Date2Chk       Date3        Date3Chk
0     2013-01-15        0          2013-02-01       1        2013-02-10         1
1     2013-02-05        1          2013-02-05       1        2013-02-10         0

期望的结果

ID    MinDate
0    2013-02-01
1    2013-02-05

假设我能得到这个结果,我不确定如何更新表格。例如,在“期望结果”中,ID 1 返回一个最小值,该最小值同时存在于 [Date1] 和 [Date2] 中;我希望用户在第一个实例上停止提醒,因此 [Date1Chk] 将设置为 0(而不是 [Date2Chk])。

4

2 回答 2

1

您可以使用CROSS APPLY.. VALUESunpivot 数据而不是UNPIVOT函数,这允许您 unpivot 到多个列:

SELECT  ID, MinDate = MIN(Date)
FROM    track
        CROSS APPLY
        (   VALUES
                (Date1, date1chk),
                (Date2, date2chk),
                (Date3, date3chk)
        ) t (Date, datechk)
WHERE   Datechk = 1
GROUP BY ID;

为了获得包含最小日期的列的名称,您可以稍微更改交叉应用以选择TOP 1而不是使用MIN

SELECT  ID, Name, MinDate = Date
FROM    track
        CROSS APPLY
        (   SELECT  TOP 1 Date, datechk, Name
            FROM    (VALUES
                        (Date1, date1chk, 'Date1'),
                        (Date2, date2chk, 'Date2'),
                        (Date3, date3chk, 'Date3')
                    ) t (Date, datechk, Name)
            WHERE   Datechk = 1
            ORDER BY Date
        ) t;

SQL Fiddle 示例

于 2013-04-14T19:32:07.183 回答
0

将 移动unpivot到子查询中,以便您可以获取列的名称。然后一个where子句解决了你的问题:

select id, name, min([date]) as mindate
from (SELECT [id], [name], d, [DATE]
      FROM track
      UNPIVOT ([DATE] FOR d IN ([date1], [date2], [date2])) unpvt
    ) t
where (d = 'date1' and datecheck1 = 1) or
      (d = 'date2' and datecheck2 = 1) or
      (d = 'date3' and datecheck3 = 1)
GROUP BY [id], [name]

要获取特定日期,请使用row_number()而不是group by

select id, name, [date] as mindate
from (select id, name, [date],
             row_number() over (partition by id, name order by [date]) as seqnum
      from (SELECT [id], [name], d, [DATE]
            FROM track
            UNPIVOT ([DATE] FOR d IN ([date1], [date2], [date2])) unpvt
          ) t
      where (d = 'date1' and datecheck1 = 1) or
            (d = 'date2' and datecheck2 = 1) or
            (d = 'date3' and datecheck3 = 1)
     ) t
where seqnum = 1
于 2013-04-14T19:11:53.980 回答