【问题标题】:Need a Complex SQL Query需要复杂的 SQL 查询
【发布时间】:2010-10-08 02:04:00
【问题描述】:

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

基本上,我需要一个查询,该查询将为每个 case_id 返回一行,其中类型为 support、状态为 start 和日期含义第一个创建的(因此在下面的示例中,只有 2009 年 2 月 1 日约翰的案例被退回,而不是 2009 年 3 月 1 日)。搜索需要是动态的,以便能够从包含数千行的表中返回所有具有不同 case_id 等的相似行。

在那之后还有更多,但我还不知道所有细节,如果你们(女孩)可以在这里帮助我,我想我可以弄清楚。 :)

身份证 |案例_ID |姓名 |日期 |状态 |类型 48 | 450 |约翰 | 2009 年 6 月 1 日 |固定 |支持 47 | 450 |约翰 | 2009 年 4 月 1 日 |搬家 |支持 46 |第451章莎拉 | 2009 年 3 月 1 日 | | 45 |第432章约翰 | 2009 年 3 月 1 日 |固定 |危急 44 | 450 |约翰 | 2009 年 3 月 1 日 |开始 |支持 42 | 450 |约翰 | 2009 年 2 月 1 日 |开始 |支持 41 | 440 |本 | 2009 年 2 月 1 日 | | 40 |第432章约翰 | 2009 年 1 月 1 日 |开始 |危急 ...

非常感谢!

编辑:

为了回答一些人的问题,我使用的是 SQL Server 2005。日期只是普通日期,而不是字符串。

好的,现在我进一步解决了这个问题。我最终得到了 Bliek 的解决方案,它就像一个魅力。但是现在我遇到了有时状态永远不会启动的问题,因为它立即解决了。我也需要将其包括在内。但仅限于特定时间段。

我想我将不得不在这里检查 FK Case_ID 引用的案例表。因此,我需要一种方法来检查过去一个月内在 CaseTable 中创建的每个 Case_ID,然后在同一个表中以与上面发布的相同方式对这些进行搜索,只返回第一个结果。我怎样才能像那样使用另一个表?

像往常一样,我会在等待中自己寻找答案,再次感谢!

编辑 2:

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

WHERE RowNumber = 1 AND Case_ID IN (SELECT Case_ID FROM CaseTable 地点(日期在“2007/11/1”和“2007/11/30”之间))

日期又搞砸了,但我确定你明白了。感谢大家的帮助!如果还有更多问题,我会回来的,但我认为有了这些信息,我可以即兴解决我目前必须处理的大多数 SQL 问题。 :)

【问题讨论】:

  • 什么数据库?在某些方面比在其他方面更容易。
  • 日期是什么类型?我认为“相当复杂”的方面是因为它是字符串而不是日期? (如果是正常的日期/时间,这只是一个简单的“分组依据”。)
  • @Stephen Darlington:不是。他感兴趣的是每组最早的记录,而不是单个值的 MIN()。
  • @Tauron Xavenberg:“立即关闭”案件的特点是什么?状态为空?状态正在“完成”且没有其他先前条目?
  • @Tomalak:除了从 Case_ID 引用的表中检查创建日期之外,基本上没有其他方法可以知道。状态可以是任何东西,看起来。但是 Case_ID 是在处理新案例时首先创建的,所以这是关键。

标签: sql dynamic


【解决方案1】:

可能是这样的:

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 打字速度快...在使用计算机的 22 年中,我认为我可以像闪电一样打字,但没有... Hunt and Peck,Hunt and Peck。
  • 我想我不是打字;我可能只是第一次看到它,它是在 15 分钟前被问到的......
  • -1 表示没有实际选择最小日期的行。如果输入了错误的名称,这将中断,因为相同的案例编号会有两行。
  • 或者即使一个案例中的两个名字是有效案例。
  • 我对选择感到疑惑——您需要使用子查询对其进行更新,以确保查询中仅包含每个 ID/名称的最小(日期)。
【解决方案2】:
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

【讨论】:

    【解决方案3】:

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

        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
    

    【讨论】:

    • 如果 ID 列是唯一的,则将“ID”列添加到 group by 语句没有帮助
    • @StingyJack:“这样更有意义”?为什么?
    • @Tomalak - 欧元日期的升序:从最小单位到最大单位对我来说比美国风格更有意义,但我仍然更喜欢英制而不是公制。去搞清楚。 @Tawani,布朗斯通有一个更好的答案,所以我投了赞成票并留下了这个。应该是删了吧。谢谢
    • @StingyJack:我倾向于在“是否排序?”中更多地查看日期格式(至少在数据处理中)。大大地。欧洲日期没有,这就是我发表评论的原因。 (对于编程之外的日常使用,我也更喜欢欧洲格式。)
    【解决方案4】:

    在 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
    

    【讨论】:

    • 像魅力一样工作!我要保存这个查询,我肯定会看到将来需要它。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-18
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 2020-02-17
    • 1970-01-01
    相关资源
    最近更新 更多