交叉选项卡 - 存储不同日期(会议1,Meeting2,会议3等)在同一列(Cross Tab -

2019-07-18 06:27发布

我需要跟踪不同的日期(动态)的。 因此,对于一个特定的任务,你可以有日期的X号来跟踪(例如DDR1会议日期,会议DDR2日期,到期日期,等等)。

我的策略是建立一个表(DateTypeID,DateDescription),这将存储每个日期的说明。 然后,我可以创建主表(ID,TaskDescription,DateTypeID)。 因此,所有的日期将是一列,你能告诉什么日期表示通过看TYPEID。 该问题在网格中显示它。 我知道我应该使用交叉表查询,但我不能让它的工作。 例如,我用一个Case语句在SQL Server 2000中过度转动的表,以便每个列名是日期类型的名称。 如果我们有如下表:

DateType表

DateTypeID | DateDescription

 1           | DDR1
 2           | DDR2
 3           | DueDate


任务表

ID | 任务描述

1 | Create Design
2 | Submit Paperwork


Tasks_DateType表

TasksID | DateTypeID | 日期

1       |     1         | 09/09/2009
1       |     2         | 10/10/2009
2       |     1         | 11/11/2009
2       |     3         | 12/12/2009


结果应该是:

TaskDescription | DDR1 | DDR2 | 截止日期

Create Design     |09/09/2009 | 10/10/2009 | null
Submit Paperwork  |11/11/2009 | null       | 12/12/2009

如果任何人有任何想法我怎么可以去研究这个,我很感激。 我做的,而不是让某个列对于每一日期,这样做的原因,有让在今后的用户,因为他们希望在不必手动列添加到表和编辑HTML代码添加尽可能多的日期的能力去做。 这还允许按类型比较日期或显示即将到来的任务简单的代码(例如,“创建设计的DDR1日期快到了”)如果任何人都可以在正确的方向指向我,我很感激。

Answer 1:

这是一个正确的答案,与您的数据进行测试。 我只用前两个日期类型,但你建立这件事上飞呢。

Select 
    Tasks.TaskDescription,     
    Min(Case DateType.DateDescription When 'DDR1' Then Tasks_DateType.Date End) As DDR1,     
    Min(Case DateType.DateDescription When 'DDR2' Then Tasks_DateType.Date End) As DDR2
From
    Tasks_DateType
    INNER JOIN Tasks ON Tasks_DateType.TaskID = Tasks.TaskID
    INNER JOIN DateType ON Tasks_DateType.DateTypeID = DateType.DateTypeID
Group By
    Tasks.TaskDescription

编辑

面包车提到,没有日期的任务将不会出现。 这是对的。 使用左连接(再次,由Van提及)和调整查询位将返回所有任务,尽管这不是你需要的时刻。

Select 
    Tasks.TaskDescription,     
    Min(Case DateType.DateDescription When 'DDR1' Then Tasks_DateType.Date End) As DDR1,     
    Min(Case DateType.DateDescription When 'DDR2' Then Tasks_DateType.Date End) As DDR2
From
    Tasks   
    LEFT OUTER JOIN Tasks_DateType ON Tasks_DateType.TaskID = Tasks.TaskID
    LEFT OUTER  JOIN DateType ON Tasks_DateType.DateTypeID = DateType.DateTypeID
Group By
    Tasks.TaskDescription


Answer 2:

如果转动列是未知的(动态的),那么你就必须在任何MS-SQL 2000或2005年,即有出不PIVOT手动建立查询。

这涉及在存储过程中任一执行动态SQL(通常一个没有没有),或者查询使用动态SQL视图。 后者是方法,我一般去。

对于旋转,我更喜欢Rozenshtein法在case语句,如下解释:

http://www.stephenforte.net/PermaLink.aspx?guid=2b0532fc-4318-4ac0-a405-15d6d813eeb8

编辑

你也可以做到这一点的LINQ到SQL,但它会发出一些非常低效的代码(至少我认为它通过linqpad),所以我不建议这样做。 如果你仍然好奇,我可以张贴的如何做到这一点的例子。



Answer 3:

我没有亲身经历与枢运营商,它可以提供更好的解决方案。

但我已经在过去使用case语句

SELECT 
    TaskDescription, 
    CASE(DateTypeID = 1, Tasks_DateType.Date) AS DDr1, 
    CASE(DateTypeID = 2, Tasks_DateType.Date) AS DDr2,
    ...
FROM Tasks 
    INNER JOIN Tasks_DateType  ON Tasks.ID = Tasks_DateType.TasksID
    INNER JOIN DateType ON Tasks_DateType.DateTypeID = DateType.DateTypeID
GROUP BY TaskDescription

这将工作,但会要求您更改SQL每当有添加了更多的任务描述,所以它的效果并不理想。

编辑:

它看起来好像在2005年SqlServer中加入了PIVOT关键字, 这个例子说明如何做到既在2000年和2005年枢轴查询,但它类似于我的答案。



Answer 4:

版本1:+简单, -必须在每次添加DateType时间来改变。 所以也不是很大一个动态的解决方案:

SELECT      tt.ID,
            tt.TaskDescription,
            td1.Date AS DDR1,
            td2.Date AS DDR2,
            td3.Date AS DueDate
FROM        Tasks tt
LEFT JOIN   Tasks_DateType td1
        ON  td1.TasksID = tt.ID AND td1.DateTypeID = 1
LEFT JOIN   Tasks_DateType td2
        ON  td2.TasksID = tt.ID AND td2.DateTypeID = 2
LEFT JOIN   Tasks_DateType td3
        ON  td3.TasksID = tt.ID AND td3.DateTypeID = 3

版本2:完全动态的(有一定的局限性,但他们可以处理-只是谷歌为它):

动态枢纽创建查询。 见动态交叉表/透视表 :你需要创建UDF的一个SP,然后可以将其用于多种用途。 这是原来的职位,对此你可能会发现很多链接和改进。

版本3: 只是把它留给你的客户端代码来处理 。 我不会设计我的SQL返回一组动态数据,而是处理它的客户端(表示层)上。 我只是不喜欢来处理来作为我的查询,在那里我需要猜测是准确的结果,一些动态列。 当结果直接呈现为一个报告表我使用的版本-2的唯一原因是。 在所有其他情况下, 真正的动态数据我使用的客户端代码。 例如:具有结构你有,你将如何连接逻辑领域DUEDATE是强制性的 - 你不能使用DB限制; 你将如何确保DDR1不高于DDR2? 如果这些都没有单独的数据库(静态)列(在这里你可以使用约束),然后客户端代码是验证你的数据一致性的一个。

祝好运!



文章来源: Cross Tab - Storing different dates (Meeting1, Meeting2, Meeting 3 etc) in the same column