如何检索每个分组中的前两个记录

时间:2013-10-23 19:44:15

标签: sql ms-access

在我的表格中,我的数据如下:

CODE    DATE    PRICE
100     1/1/13  $500
100     2/1/13  $521
100     3/3/13  $530
100     5/9/13  $542
222     3/3/13  $20
350     1/1/13  $200
350     3/1/13  $225

是否可以创建查询以按DATE提取两个最新记录?并且仅当特定代码有2个以上的日期时。结果将是:

CODE    DATE    PRICE
100     5/9/13  $542
100     3/3/13  $530
350     3/1/13  $225
350     1/1/13  $200

如果您可以将两个价格/日期放在同一行上,则可获得奖励积分,如下所示:

CODE    OLD_DATE    OLD_PRICE    NEW_DATE    NEW_PRICE
100     3/3/13      $530         5/9/13      $542
350     1/1/13      $200         3/1/13      $225

谢谢!!!

2 个答案:

答案 0 :(得分:1)

我设法用5个子查询和1个汇总查询来解决它。

首先,我们有一个子查询,为每个代码提供MAX日期。 接下来,我们执行相同的子查询,但我们排除了以前的结果。 我们假设您的数据已经汇总,并且您不会有相同代码的重复日期。

接下来,我们为最新和第二个最新日期带来相应的代码/价格。如果第二个Max查询中不存在代码 - 那么我们根本不包含它。

在联合查询中,我们将两者的结果结合起来。在Rollup Query中,我们正在排序并删除union中生成的空值。

<强>结果:

CODE    MaxOfOLDDATE    MaxOfOLDPRICE   MaxOfNEWDATE    MaxOfNEWPRICE
100     2013-03-03      $530.00     2013-05-09      542
350     2013-01-01      $200.00     2013-03-01      225

在名为“Table”的表格中使用您的数据,创建以下查询:

<强> SUB_2ndMaxDatesPerCode:

SELECT Table.CODE, Max(Table.Date) AS MaxOfDATE1
FROM SUB_MaxDatesPerCode RIGHT JOIN [Table] ON (SUB_MaxDatesPerCode.MaxOfDATE = Table.DATE) AND (SUB_MaxDatesPerCode.CODE = Table.CODE)
GROUP BY Table.CODE, SUB_MaxDatesPerCode.CODE
HAVING (((SUB_MaxDatesPerCode.CODE) Is Null));

<强> SUB_MaxDatesPerCode:

SELECT Table.CODE, Max(Table.Date) AS MaxOfDATE
FROM [Table]
GROUP BY Table.CODE;

<强> SUB_2ndMaxData:

SELECT Table.CODE, Table.Date, Table.PRICE
FROM [Table] INNER JOIN SUB_2ndMaxDatesPerCode ON (Table.DATE = SUB_2ndMaxDatesPerCode.MaxOfDATE1) AND (Table.CODE = SUB_2ndMaxDatesPerCode.Table.CODE);

<强> SUB_MaxData:

SELECT Table.CODE, Table.Date, Table.PRICE
FROM ([Table] INNER JOIN SUB_MaxDatesPerCode ON (Table.DATE =  SUB_MaxDatesPerCode.MaxOfDATE) AND (Table.CODE = SUB_MaxDatesPerCode.CODE)) INNER JOIN SUB_2ndMaxDatesPerCode ON Table.CODE = SUB_2ndMaxDatesPerCode.Table.CODE;

<强> SUB_Data:

SELECT CODE, DATE AS OLDDATE, PRICE AS OLDPRICE, NULL AS NEWDATE, NULL AS NEWPRICE FROM SUB_2ndMaxData;
UNION ALL SELECT CODE, NULL AS OLDDATE, NULL AS OLDPRICE, DATE AS NEWDATE, PRICE AS NEWPRICE FROM SUB_MaxData;

数据(汇总):

SELECT SUB_Data.CODE, Max(SUB_Data.OLDDATE) AS MaxOfOLDDATE, Max(SUB_Data.OLDPRICE) AS MaxOfOLDPRICE, Max(SUB_Data.NEWDATE) AS MaxOfNEWDATE, Max(SUB_Data.NEWPRICE) AS MaxOfNEWPRICE
FROM SUB_Data
GROUP BY SUB_Data.CODE
ORDER BY SUB_Data.CODE;

你去了 - 感谢你的挑战。

答案 1 :(得分:0)

访问最近的数据

要访问最近的数据,请使用TOP 2。比如从表中反转数据,然后选择前2个。就像从ZYX开始ABC并选择可以为你提供ZY的TOP 2.

SELECT TOP 2 * FROM table_name ORDER BY column_time DESC;

这样,您可以反转表格,然后从顶部选择最近的两个。

加入表格

要加入两列并根据任务创建结果,您可以使用JOIN(INNER JOIN;我更喜欢这个),例如:

SELECT TOP 2 * FROM table_name INNER JOIN table_name.column_name ON 
table_name.column_name2

这样,您将连接两个表中的值与两个表中另一列的值匹配的表。

您可以使用for循环来为它们选择值,或者您可以在foreach循环中使用它来取出它们的值。

我的建议

我最好的方法是,首先选择使用日期订购的数据。

然后在foreach()循环内,您将为其编写数据,选择该时间的剩余数据。并将其写入该循环内。

代码(column_name)不会打扰你

当您使用ORDER By Time Desc引用查询时,您将不再使用CODE,例如WHERE Code = value。您将获得最新的代码。如果您确实需要code列,则可以使用和if else阻止它。

参考:

http://technet.microsoft.com/en-us/library/ms190014(v=sql.105).aspx(内部联接)

http://www.w3schools.com/sql/sql_func_first.asp(顶部;检查Sql Server查询)