您如何检索每个分组中的前两条记录
Posted
技术标签:
【中文标题】您如何检索每个分组中的前两条记录【英文标题】:How do you retrieve the top two records within each grouping 【发布时间】:2013-10-23 19:44:15 【问题描述】:在我的表中,我的数据如下所示:
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
谢谢!!!
【问题讨论】:
来吧,杰夫。有了 50 多个问题,您应该知道接下来会发生什么……您尝试过什么,尝试过什么? How to select top 10 in Access query?的可能重复 @GordThompson 我尝试了以DATE
作为标题和PRICE
作为值的交叉表查询,但它为表中的每个日期创建了一个列。
【参考方案1】:
我设法用 5 个子查询和 1 个汇总查询解决了这个问题。
首先我们有一个子查询,它为我们提供每个代码的 MAX 日期。 接下来,我们执行相同的子查询,只是我们排除了之前的结果。 我们假设您的数据已经汇总,并且您不会有相同代码的重复日期。
接下来,我们为最近和第二个最晚日期输入适当的代码/价格。如果代码在 2nd Max 查询中不存在 - 那么我们根本不包含它。
在联合查询中,我们将两者的结果结合起来。在汇总查询中,我们对联合中生成的空值进行排序和删除。
结果:
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
在名为“表”的表中使用您的数据,创建以下查询:
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;
你去 - 谢谢你的挑战。
【讨论】:
谢谢!这就是我一直在寻找的......获取最近日期的过程,然后是第二个最近的日期,然后是每个日期的价格,然后将它们放在一起。我无法在脑海中解决这个问题。【参考方案2】:访问最近的数据
要访问最近的数据,请使用TOP 2
。比如你把表中的数据倒过来,然后选择top 2。就像你从ZYX开始ABC,然后选择TOP 2,它会给你提供ZY。
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
引用查询时,您将不再使用代码,例如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 查询)
【讨论】:
谢谢 .. 我不知道TOP 2
是一个东西。我过去做过TOP 10
,但没想过要尝试其他数字。我会试试看的!!
当然,您可以尝试任何数字来选择最高值:)
我认为比这更复杂。这只会为您提供前 2 条记录,而不是按代码显示的前 2 条记录。
我从来没有提到他想要 CODE 的前 2 条记录的 OP。 :) 他只想要 TOP 2 列 :)
事实上,他想忽略CODE,这样他就不必担心不同代码的匹配日期。不是这样吗?以上是关于您如何检索每个分组中的前两条记录的主要内容,如果未能解决你的问题,请参考以下文章