【问题标题】:Max Date/Case Statement最大日期/案例陈述
【发布时间】:2017-07-03 04:49:04
【问题描述】:

我正在尝试根据其中一列的最大日期拉回一行详细信息。做一个简单的 max(date.field) 不适用于我的表。我最初是通过利用我使用此资源See the entry by Tom H. 构建的此查询来解决该问题的:

SELECT
    HBM_CLIENT.CLIENT_CODE,
    HBM_NAME.NAME AS CLIENT_NAME,
    PART_BILL1.PART_CAT_CODE AS BILLING_CODE,
    PART_BILL1.EMPL_UNO AS BILLING_NAME_UNO,
    HBM_PERSNL_BILL.EMPLOYEE_NAME AS BILLING_NAME,
    PART_BILL1.PERCENTAGE AS BILLING_PERCENTAGE
FROM 
    HBM_CLIENT
INNER JOIN 
    HBM_NAME ON HBM_CLIENT.NAME_UNO = HBM_NAME.NAME_UNO
LEFT OUTER JOIN 
    TBM_CLMAT_PART AS PART_BILL1 ON PART_BILL1.CLIENT_UNO = HBM_CLIENT.CLIENT_UNO
                                 AND PART_BILL1.PART_CAT_CODE = 'BILL'
LEFT OUTER JOIN 
    TBM_CLMAT_PART AS PART_BILL2 ON PART_BILL2.CLIENT_UNO = HBM_CLIENT.CLIENT_UNO
                                 AND PART_BILL2.EFF_DATE > PART_BILL1.EFF_DATE
                                 AND PART_BILL1.PART_CAT_CODE = 'BILL'
LEFT OUTER JOIN 
    HBM_PERSNL AS HBM_PERSNL_BILL ON PART_BILL1.EMPL_UNO = HBM_PERSNL_BILL.EMPL_UNO
GROUP BY 
    HBM_CLIENT.CLIENT_CODE, HBM_NAME.NAME,
    PART_BILL1.PART_CAT_CODE, PART_BILL1.EMPL_UNO,
    HBM_PERSNL_BILL.EMPLOYEE_NAME,
    PART_BILL1.PERCENTAGE,
ORDER BY 
    HBM_CLIENT.CLIENT_CODE

这个查询的问题是,由于某种原因,它并没有拉回所有的结果,原因是因为我使用的解决方案。

我想知道使用 case 语句是否更有意义,但我对 case 语句不是很熟悉。

这是我正在处理的查询:

`SELECT
  HBM_CLIENT.CLIENT_CODE,
  HBM_NAME.NAME AS CLIENT_NAME,
  PART_BILL1.PART_CAT_CODE AS BILLING_CODE,
  PART_BILL1.EMPL_UNO AS BILLING_NAME_UNO,
  HBM_PERSNL_BILL.EMPLOYEE_NAME AS BILLING_NAME,
  PART_BILL1.PERCENTAGE AS BILLING_PERCENTAGE,
  Part_BILL1.EFF_DATE,
 CASE
    WHEN 
    MAX(Part_BILL1.EFF_DATE) > Part_BILL1.EFF_DATE THEN max(Part_BILL1.EFF_DATE) ELSE Part_BILL1.EFF_DATE END  
FROM HBM_CLIENT
INNER JOIN HBM_MATTER
  ON HBM_CLIENT.CLIENT_UNO = HBM_MATTER.CLIENT_UNO
INNER JOIN HBM_NAME
  ON HBM_CLIENT.NAME_UNO = HBM_NAME.NAME_UNO
LEFT OUTER JOIN TBM_CLMAT_PART AS PART_BILL1
  ON PART_BILL1.CLIENT_UNO = HBM_CLIENT.CLIENT_UNO
  AND PART_BILL1.PART_CAT_CODE = 'BILL'
LEFT OUTER JOIN HBM_PERSNL AS HBM_PERSNL_BILL
  ON PART_BILL1.EMPL_UNO = HBM_PERSNL_BILL.EMPL_UNO
WHERE 
(HBM_CLIENT.CLIENT_CODE = '065011') 
GROUP BY
  HBM_CLIENT.CLIENT_CODE,
  HBM_NAME.NAME,
  PART_BILL1.PART_CAT_CODE,
  PART_BILL1.EMPL_UNO,
  HBM_PERSNL_BILL.EMPLOYEE_NAME,
  PART_BILL1.PERCENTAGE,
  Part_BILL1.EFF_DATE
HAVING 
(Part_BILL1.EFF_DATE = CASE
WHEN MAX(Part_BILL1.EFF_DATE) > Part_BILL1.EFF_DATE THEN max(Part_BILL1.EFF_DATE) ELSE Part_BILL1.EFF_DATE END)`

它运行,但它给了我两行而不是一排,即它不只是拉最大。我正在使用 T-SQL 并使用 Visual Studio 编写 SSRS。

我很乐意回答我能回答的任何问题。如果我的解释不是很好,我提前道歉。

| CLIENT_CODE | CLIENT_NAME  | BILLING_NAME | EFF_DATE | PERCENTAGE |
| ------------+--------------+--------------+----------+------------|
| 123456      | Entity, Inc. | Attorney A   | 1/1/1990 |50%         |
| 123456      | Entity, Inc. | Attorney B   | 1/1/1990 |50%         |
| 123456      | Entity, Inc. | Attorney B   | 1/1/2017 |50%         |
| 123456      | Entity, Inc. | Attorney C   | 1/1/2017 |50%         |

【问题讨论】:

  • 在您提供的参考资料中,您对给出的数据有一个特定的问题。您提供了大量表格,却不知道其中有什么。有什么方法可以在测试数据中提供更简化的版本?如果没有看到基础数据,很难提供这么多具体的细节。
  • @djangojazz 这很合理!我已经删除了额外的东西,所以它几乎是一样的。现在显示的唯一表格是使用我选择的字段运行查询所需的表格。

标签: sql-server tsql reporting-services


【解决方案1】:

这不能通过使用带有ORDER BY 子句的SELECT TOP 1 查询来简化吗?

类似这样的:

SELECT TOP 1
  HBM_CLIENT.CLIENT_CODE,
  HBM_NAME.NAME AS CLIENT_NAME,
  PART_BILL1.PART_CAT_CODE AS BILLING_CODE,
  PART_BILL1.EMPL_UNO AS BILLING_NAME_UNO,
  HBM_PERSNL_BILL.EMPLOYEE_NAME AS BILLING_NAME,
  PART_BILL1.PERCENTAGE AS BILLING_PERCENTAGE,
  Part_BILL1.EFF_DATE,
  ....
FROM HBM_CLIENT
INNER JOIN HBM_MATTER
  ON HBM_CLIENT.CLIENT_UNO = HBM_MATTER.CLIENT_UNO
INNER JOIN HBM_NAME
  ON HBM_CLIENT.NAME_UNO = HBM_NAME.NAME_UNO
LEFT OUTER JOIN TBM_CLMAT_PART AS PART_BILL1
  ON PART_BILL1.CLIENT_UNO = HBM_CLIENT.CLIENT_UNO
  AND PART_BILL1.PART_CAT_CODE = 'BILL'
LEFT OUTER JOIN HBM_PERSNL AS HBM_PERSNL_BILL
  ON PART_BILL1.EMPL_UNO = HBM_PERSNL_BILL.EMPL_UNO
WHERE 
(HBM_CLIENT.CLIENT_CODE = '065011') 
ORDER BY Part_BILL1.EFF_DATE DESC

这应该只为您提供 EFF_DATE 的最新行,而不需要任何特殊的分组或案例逻辑。

编辑:在我看来,获得所需结果的最佳方法是利用 TOP 子句。通常,在编写查询时 像这样,你会写 SELECT TOP 1SELECT TOP 1000,但是 TOPclause 还支持各种功能。您可以使用 子查询、计算、变量以及WITH TIES 获得您想要的功能。

在您的情况下,您希望查询返回任意数量的行,如此长 因为它们都具有相同的EFF_DATE 值,这也将是 表中给定CLIENT_CODE 的最大EFF_DATE 值。

因此,我建议只需将 WITH TIES 参数添加到 TOP 子句以获得您正在寻找的功能:

SELECT TOP 1 WITH TIES
  HBM_CLIENT.CLIENT_CODE,
  HBM_NAME.NAME AS CLIENT_NAME,
  PART_BILL1.PART_CAT_CODE AS BILLING_CODE,
  PART_BILL1.EMPL_UNO AS BILLING_NAME_UNO,
  HBM_PERSNL_BILL.EMPLOYEE_NAME AS BILLING_NAME,
  PART_BILL1.PERCENTAGE AS BILLING_PERCENTAGE,
  Part_BILL1.EFF_DATE,
  ....
FROM HBM_CLIENT
INNER JOIN HBM_MATTER
  ON HBM_CLIENT.CLIENT_UNO = HBM_MATTER.CLIENT_UNO
INNER JOIN HBM_NAME
  ON HBM_CLIENT.NAME_UNO = HBM_NAME.NAME_UNO
LEFT OUTER JOIN TBM_CLMAT_PART AS PART_BILL1
  ON PART_BILL1.CLIENT_UNO = HBM_CLIENT.CLIENT_UNO
  AND PART_BILL1.PART_CAT_CODE = 'BILL'
LEFT OUTER JOIN HBM_PERSNL AS HBM_PERSNL_BILL
  ON PART_BILL1.EMPL_UNO = HBM_PERSNL_BILL.EMPL_UNO
WHERE 
(HBM_CLIENT.CLIENT_CODE = '065011') 
ORDER BY Part_BILL1.EFF_DATE DESC

TOP子句的各种用法的完整解释可以是 找到here.

简单解释一下,WITH TIES 参数意味着您想要 查询以根据值返回数据集的TOP X 行 在ORDER BY 子句中-在您的情况下为EFF_DATE。所以如果有 EFF_DATE 中的两行具有相同值,或者三行,或者五行 一百,它们都会被退回,因为你是有效的 不是搜索TOP 1 ROW,而是搜索 TOP 1 VALUE of EFF_DATE

希望对您有所帮助。

【讨论】:

  • 如果我没记错的话,它不会起作用,因为可能有两个律师在同一日期列出。有一个名为 Part_bill1.percentage 的字段。在该列中,这些律师中的每一个都将获得 50% 的信用。我在手机上,所以我可以修改上面的表格,但想象一下,在 1999 年,律师 a 和律师 b 都获得了 50 50 学分。 2017 年,律师 b 退休,因此律师 a 将律师 ç 添加为新的联合出票人。所以在那种情况下,我需要拉回两行显示律师 a 和律师 ç。我会尽快尝试您的建议,但我认为 top 和 max 是我做的第一件事。
  • @T.Meyer 从您的问题中我不明白您正在寻找不止一行。您明确表示您想要“基于其中一列的最大日期的详细信息行”。在您描述的实例中,您说的是聚合行 - 即,您希望在一行中列出两个不同的律师,应该按最大日期选择?
  • @T.Meyer 需要特别清楚:你想要一排还是两排?如果有,您希望如何显示聚合数据?例如,两名律师 (B & C) 于 2017 年 1 月 1 日处理客户 123456 的案件,因此每人获得 50% 的信用。那么您是否希望查看 Client_Code、Client_Name、Billing_Name(聚合,可能包含百分比作为值的一部分)、Eff_Date?
  • 对不起。我是自学这些东西,所以我很难解释。我更新了上面的表格。我想根据最大日期获取行,这意味着在上面的示例中它将拉 2 行。如果我们做了前 1,那么它只返回我需要的那两行之一。再次抱歉,造成混淆。
  • 我忘了回答你问题的第二部分。我想将每列的百分比作为单独的列返回,而不是与聚合的最大日期相结合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-07
  • 2023-01-13
  • 2023-04-10
  • 2010-10-30
  • 2016-05-13
  • 2016-02-21
  • 1970-01-01
相关资源
最近更新 更多