我总是很难理解GROUP BY的功能,这个也不例外。
我有一个简单的Join查询,如Select t1.g1, t1.g2, t2.id, t2.datetime, t3.name
From ((table1 t1 Inner Join table2 t2 on t1.fld1=t2.fld1)
Inner Join table3 t3 on t1.fld2=t3.fld2)
Order By t2.datetime, t2.id
按预期返回我的数据。以下是一些示例行,说明我试图使用Group By…
检索的内容。我想只抓取t1的每个组的第一行。g1, t1.g2。
你不需要聚合。您希望过滤数据。在本例中,相关子查询可以满足您的要求:
Select t1.g1, t1.g2, t2.id, t2.datetime, t3.name
From (table1 t1 Inner Join
table2 t2
on t1.fld1 = t2.fld1
) Inner Join
table3 t3
on t1.fld2 = t3.fld2
where t2.id = (select top 1 tt2.id
from (table1 tt1 Inner Join
table2 tt2
on tt1.fld1 = tt2.fld1
) Inner Join
table3 tt3
on tt1.fld2 = tt3.fld2
where tt1.g1 = t1.g1 and tt1.g2 = t1.g2
order by tt2.datetime, tt2.id
);
这是一个很好的解决方案(6s在250k recs在t2),并做我所要求的。
我无法让Gordon的答案在Access中工作。然而,它似乎应该如此。我对它在2年的25万次记录下的表现表示怀疑。如果我能弄清楚如何让Access使用它,我很想测试像Gordon那样的解决方案。
请参阅问题描述,以获得我所追求的记录的示例。我只需要t2.id从结果集中。最初并没有说明这一点,但我看不出这对问题陈述或解决方案有什么影响。我可能错了。我仍然需要t3.name,但稍后可以使用t2.id检索它。
但是我仍然需要选择记录GROUP'd BYt1。g1, t1.g2当所有记录按t2排序时,它首先出现。dateandtime, t2.id. 或者换一种说法,在所有相同t1的记录中。g2,我需要的是组按t2排序时的第一个记录。dateandtime t2.id" .
也许我正在考虑这个解决方案,我的问题都错了,有更好的方法来解决这个与SQL;如果是的话,我很乐意听一听。
我似乎已经了解到GROUP BY根据这个SQL子句将记录分组在一起,但是这个分组在这一点上失去了单个记录的任何概念;例如,您只能通过使用聚合函数(MIN, MAX, SUM等)提取其他字段,但是-重要的是- FIRST不会获得您可以预测的记录的值,因为ORDER by子句尚未执行。
说了这么多,下面是我的解决方案。
- 我删除了对t3上Join的引用如t2.id我可以在事后使用t2.id从t3检索所需的所有其他信息。
- 不需要选择"t1"。g1, t1。G2 '是多余的。我最初认为任何Group By字段也必须在Select子句中指定。
- 我合并t2。日期和时间和t2。id到一个文本字段,并使用MIN来选择数据/记录我之后,一旦它是GROUP'd BY。不需要排序我的结果集,作为记录的最小值t2。日期和时间,然后是t2。我被选中了!从而满足我的条件和选择正确的记录。
- 因为我只需要t2。id返回用于进一步处理,我提取t2。从#3中内置的字符串id转换回长数据类型。
这是一个简短而简单的查询:
Select
MIN(Format(t2.dateandtime, "yyyymmddhhmmss") & '_' & Format(t2.id, '000000')) as dt_id,
CLNG(MID(dt_id, INSTR(dt_id, '_') + 1)) as id
From
(table1 t1 Inner Join table2 t2 on t1.fld1=t2.fld1)
Group By
t1.g1, t1.g2