【问题标题】:SQL / stored proc for SELECT Distinct rows with max date <= provided dateSELECT 不同行的 SQL / 存储过程,最大日期 <= 提供日期
【发布时间】:2014-06-03 00:09:41
【问题描述】:

提前致谢:请考虑以下表格:

Table 1: matrix_data
Matrix_ID   Data_ID     DATE(Date)  Info(varchar)
1               1       3000            A
1               1       3500            B
1               2       3600            C
1               2       3700            D
2               1       3100            E
2               1       3400            F
2               2       3450            G   
2               2       3750            H
3               1       3000            I
3               1       3500            J
3               2       3620            K
3               2       3700            L
4               1       3100            M
4               1       3400            N
4               2       3450            O
4               2       3750            P

Table 2:  Result_Query
Result_ID           Matrix_ID
22                  1
22                  3

鉴于以下 -

A Date (for example - 3640)
A Data_ID (For example - 2)
A Result_ID (For example - 22)

我需要一个查询,该查询将为每个具有与 Result_ID (22) 对应的记录的 Matrix_id 返回一行。 对于也与提供的 Data_ID (2) 匹配的记录,该行应包含最大 DATE

For the example provided, the result would be :

Matrix_ID   Data_ID     DATE    Info(varchar)
1               2       3600        C
3               2       3620        K

我无法更改表格。这是一个小例子,但我可能在 Result_ID 中有 5000 个矩阵 ID,所以我喜欢这样做,而不需要为每条记录都访问数据库。 存储过程是一个选项,如果我可以使用直接 sql 更好。 我正在使用甲骨文。 DATE 是日期列而不是数字。再次感谢 -

到目前为止 - 我试图简化问题并只是这样做:

select *
    from ( select b.* , rank() over ( partition by data_id, matrix_id order by DATE desc ) rnk
    from matrix_data b )
where rnk = 1

我现在需要折叠其余的约束

【问题讨论】:

标签: sql oracle greatest-n-per-group


【解决方案1】:

一个简单的分组就足够了。

SELECT d.matrix_id, d.data_id, MAX(d.the_date) FROM matrix_data d
INNER JOIN result_query q ON q.matrix_id = d.matrix_id
WHERE d.data_id = ?
AND q.result_id = ?
AND d.the_date <= ?
GROUP BY d.matrix_id, d.data_id;

要包含info,您需要查询此查询:

WITH q1 AS
    (SELECT d.matrix_id, d.data_id, MAX(d.the_date) AS maxdate FROM matrix_data d
    INNER JOIN result_query q ON q.matrix_id = d.matrix_id
    WHERE d.data_id = ?
    AND q.result_id = ?
    AND d.the_date <= ?
    GROUP BY d.matrix_id, d.data_id)
SELECT q1.*, d.info FROM matrix_data d
INNER JOIN q1 ON q1.matrix_id = d.matrix_id
AND q1.maxdate = d.the_date
AND q1.data_id = d.data_id;

【讨论】:

  • 谢谢 - 我遇到了错误。表 1 中的 DATE 列是 DATE 数据类型 - 它似乎不喜欢 max(d.date)。我还在寻找其他具有 rank 功能的选项 - 我没有意识到这是一个分类良好的 n-per-group 问题。
  • 这不是问题。您得到的确切错误是什么?
  • 以下内容:ORA-00979:不是 GROUP BY 表达式 00979. 00000 - “不是 GROUP BY 表达式” *原因:*操作:- 我实际上在下面有一个工作示例,但我想也可以通过工作获得简单的组 - 一个问题 - 为什么 d.info 在 group by 子句中?
  • d.info 不应出现在 group 子句中。如果您想在结果中包含信息,我编辑了我的答案并添加了第二个解决方案。
【解决方案2】:

目前看来可行的解决方案:

有什么办法优化吗?

SELECT Matrix_ID, Data_ID, DATE, Info
FROM ( SELECT M.*, rank() OVER ( PARTITION BY matrix_id, data_id ORDER BY DATE DESC ) rnk FROM matrix_data M 
JOIN RESULT_QUERY Q ON M.MATRIX_ID = Q.MATRIX_ID 
WHERE Q.RESULT_ID = 22
AND M.DATE <= to_date('12/20/1909','mm/dd/yyyy') )
WHERE rnk = 1;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-14
    • 1970-01-01
    • 2017-03-30
    • 2019-08-09
    • 1970-01-01
    • 2014-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多