需要复杂的SQL查询

时间:2009-02-17 12:59:51

标签: sql dynamic

我需要做一个相当复杂的查询,我需要帮助不好。以下是我做的一个例子。

基本上,我需要一个查询,为每个 case_id 返回一行,其中类型为支持,状态为开始,日期含义第一个创建的(所以在下面的例子中,只有2/1/2009 John的案例被返回,而不是3/1/2009)。搜索需要是动态的,以便能够从具有数千行的表中返回具有不同case_id等的所有类似行。

之后还有更多,但我还不知道所有的细节,我想如果你们(一个女性)可以帮助我,我可以弄明白。 :)

ID   |  Case_ID   |   Name   |   Date   |  Status  |  Type   

48   |    450     |   John   | 6/1/2009 |  Fixed   | Support   
47   |    450     |   John   | 4/1/2009 |  Moved   | Support   
46   |    451     |   Sarah  | 3/1/2009 |          |           
45   |    432     |   John   | 3/1/2009 |  Fixed   | Critical  
44   |    450     |   John   | 3/1/2009 |  Start   | Support 
42   |    450     |   John   | 2/1/2009 |  Start   | Support   
41   |    440     |   Ben    | 2/1/2009 |          |           
40   |    432     |   John   | 1/1/2009 |  Start   | Critical  
...

非常感谢!

编辑:

为了回答一些人的问题,我正在使用SQL Server 2005.日期只是简单的日期,而不是字符串。

好的,现在我进一步解决了这个问题。我最终得到了Bliek的解决方案,它就像一个魅力。但现在我遇到了一个问题,有时状态永远不会开始,因为它立即得到解决。我也需要包含它。但只是在一段时间内。

我想我必须在这里检查FK Case_ID引用的案例表。所以我需要一种方法来检查过去一个月内在CaseTable中创建的每个Case_ID,然后在同一个表中以与上面发布的相同方式搜索这些Case_ID,只返回第一个结果。我该如何使用其他表呢?

像往常一样,我会在等待时尝试找到答案,再次感谢!

编辑2:

似乎这就是答案。我还没有访问完整的数据库所以我无法完全测试它,但它似乎正在使用我创建的虚拟表,继续从Bliek的代码的WHERE子句:

WHERE RowNumber = 1 AND Case_ID IN (SELECT Case_ID FROM CaseTable
      WHERE (Date BETWEEN '2007/11/1' AND '2007/11/30'))

日期再次被搞砸,但你明白了我的想法。感谢大家的帮助!如果有更多问题我会回来,但我认为通过这些信息,我可以即兴完成我目前必须处理的大多数SQL问题。 :)

4 个答案:

答案 0 :(得分:4)

可能是这样的:

select Case_ID, Name, MIN(date), Status, Type 
from table
where type = 'Support'
 and status = 'Start'
group by Case_ID, Name, Status, Type 
编辑:你没有提供很多关于你真正想要的细节,所以我建议你阅读所有答案并选择最适合你问题的答案。到目前为止,我要说Tomalak的回答最接近你所寻找的......

答案 1 :(得分:3)

SELECT
  c.ID,
  c.Case_ID,
  c.Name,
  c.Date,
  c.Status,
  c.Type
FROM
  CaseTable c
WHERE
  c.Type = 'Support'
  AND c.Status = 'Start'
  AND c.Date = (
    SELECT MIN(Date) 
    FROM CaseTable
    WHERE Case_ID = c.Case_ID AND Type = c.Type AND Status = c.Status)
/* GROUP BY only needed when for a given Case_ID several rows 
   exist that fulfill the WHERE clause */
GROUP BY
  c.ID,
  c.Case_ID,
  c.Name,
  c.Date,
  c.Status,
  c.Type

此查询从Case_IDDateStatusType列的索引中获益匪浅。

虽然SupportStatus上的过滤器只需要在一个地方设置,但增加了价值。

作为GROUP BY子句的替代方案,您可以执行SELECT DISTINCT,这会增加可读性(这可能会也可能不会影响整体性能,我建议您相互衡量两种变体)。如果您确定表中没有Case_ID,则存在两行具有相同日期的行,您根本不需要GROUP BYSELECT DISTINCT

答案 2 :(得分:1)

在SQL Server 2005及更高版本中,我将使用公用表表达式(CTE)。这提供了很多可能性:

With ResultTable (RowNumber
                 ,ID
                 ,Case_ID
                 ,Name
                 ,Date
                 ,Status
                 ,Type)
AS
(
    SELECT Row_Number() OVER (PARTITION BY Case_ID
                                  ORDER BY Date ASC)

          ,ID
          ,Case_ID
          ,Name
          ,Date
          ,Status
          ,Type
      FROM CaseTable
     WHERE Type   = 'Support'
       AND Status = 'Start'
)
    SELECT ID
          ,Case_ID
          ,Name
          ,Date
          ,Status
          ,Type
      FROM ResultTable
     WHERE RowNumber = 1

答案 3 :(得分:0)

不要为你的日期格式道歉,这样更有道理。

    SELECT ID, Case_ID, Name, MIN(Date), Status, Type
    FROM caseTable
    WHERE Type = 'Support'
       AND status = 'Start'
    GROUP BY ID, Case_ID, Name, Status, Type