如何在单个SQL查询中选择每个字段的第k条记录

时间:2019-05-23 22:09:48

标签: sql sqlite select

请帮助我解决以下问题。我已经花了一个星期的时间试图将所有逻辑放入一个SQL查询中,但仍然没有得到满意的结果。我希望SQL专家可以给我一个提示,

我有一个表,其中包含4个字段:日期,expire_month,expire_year和值。主键在前三个字段中定义。因此,对于一个具体的日期,几乎没有几个值具有不同的expire_month,expire_year。我需要为每个日期从表中选择一个值。

例如,当我执行查询时:

SELECT date, expire_month, expire_year, value FROM futures 
WHERE date = ‘1989-12-01' ORDER BY expire_year, expire_month;

我得到了同一日期的值列表,按有效期排序(月份用字母编码):

1989-12-01  Z   1989    408.25
1989-12-01  H   1990    408.25
1989-12-01  K   1990    389
1989-12-01  N   1990    359.75
1989-12-01  U   1990    364.5
1989-12-01  Z   1990    375

该日期的正确单个值是从顶部开始的第k条记录。例如,k中的k为2,则“正确的单个”记录将为:

1989-12-01  H   1990    408.25

如何为表格中的每个日期选择这些“正确的单个”值?

3 个答案:

答案 0 :(得分:2)

您可以使用rank()来做到这一点:

source==TestButton

子查询中的列 if(e.getSource()==YesButton) { DisplayText = "Word added to Anadrome list."; Test_Anadrome.setText(DisplayText); } if(e.getSource()==NoButton) { DisplayText = "Type a different word and press the 'Test Word' Button."; Test_Anadrome.setText(DisplayText); } 实际上是按select t.date, t.expire_month, t.expire_year, t.value from ( select *, rank() over(partition by date order by expire_year, expire_month) rn from futures ) t where t.rn = 2 分组的行的排名。
rn更改为所需等级。

答案 1 :(得分:1)

虽然forpas的答案是更好的答案(尽管我认为我在这里使用row_number()而不是rank()),但是窗口函数是Sqlite的最新添加(在3.25中)。如果您使用的是旧版本并且无法升级,请使用以下替代方法:

SELECT date, expire_month, expire_year, value
FROM futures AS f
WHERE (date, expire_month, expire_year) =
      (SELECT f2.date, f2.expire_month, f2.expire_year
       FROM futures AS f2
       WHERE f.date = f2.date
       ORDER BY f2.expire_year, f2.expire_month
       LIMIT 1 OFFSET 1)
ORDER BY date;

OFFSET的值比第K行小1,因此第二行为1,第三行为2,依此类推。

但是,它为表中的每一行执行一个相关的子查询,但这并不理想。希望您的复合主键列按date, expire_year, expire_month的顺序排列,这将通过消除其中的其他排序需求而大有帮助。

答案 2 :(得分:-2)

您可以尝试以下查询。

select * from 
(
SELECT rownum seq, date1, expire_month, expire_year, value FROM testtable
WHERE date1 = to_date('1989-12-01','yyyy-mm-dd') 
ORDER BY expire_year, expire_month
)
where seq=2