總是很難將我的頭放在 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 | t2.g2 | t2.id | t2.datetime | t3.name |
|---|---|---|---|---|
| 726 | 4506 | 32 | 2021 年 9 月 12 日 | 姓名A |
| 726 | 4506 | 33 | 2021 年 9 月 12 日 | 姓名B |
| 726 | 4506 | 30 | 2021 年 9 月 13 日 | 姓名C |
我想抓住ONLY第一行中的每一組t1.g1,t1.g2。
所以,我嘗試以下操作:
Select t1.g1, t1.g2, FIRST(t2.id), FIRST(t2.datetime), FIRST(t3.name)
From ((table1 t1 Inner Join table2 t2 on t1.fld1=t2.fld1)
Inner Join table3 t3 on t1.fld2=t3.fld2)
Group By t1.g1, t1.g2
Order By FIRST(t2.datetime), FIRST(t2.id)
對于上面的示例組,這將回傳以下記錄...
| t1.g1 | t2.g2 | t2.id | t2.datetime | t3.name |
|---|---|---|---|---|
| 726 | 4506 | 30 | 2021 年 9 月 13 日 | 姓名C |
因此,Order By在分組完成后運行,而不是之前。或者看起來是這樣。也許是 SQL 關鍵字順序的原因(Select、From、Where、Group By、Order By)。好吧,如果我的假設是正確的,那是有道理的。我認為它在其他 726/4506 條記錄之前找到 t2.id=30,因為 t2.id 是 table2 上的主鍵。
所以,現在我嘗試嵌套查詢,其中我上面的第一個查詢以正確的順序回傳資料,外部查詢分組并獲取第一條記錄。
Select t1.g1, t1.g2, FIRST(t2.id), FIRST(t2.datetime), FIRST(t3.name)
FROM (
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
Order By FIRST(t2.datetime), FIRST(t2.id)
結果一樣!我不知道這是怎么發生的。因此,如果有人可以闡明在這種情況下 Access SQL 的幕后功能順序,我很想知道。在我的第二個查詢(嵌套選擇)中,似乎我正在對目標資料進行排序,以便在對 FIRST() 聚合函式進行分組之后,應該選擇在內部結果集中找到的第一行。但這并沒有發生。
當然,如果有人能告訴我如何回傳我所追求的行......
| t1.g1 | t2.g2 | t2.id | t2.datetime | t3.name |
|---|---|---|---|---|
| 726 | 4506 | 32 | 2021 年 9 月 12 日 | 姓名A |
這就是我真正需要的。
uj5u.com熱心網友回復:
我只想抓取 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
);
uj5u.com熱心網友回復:
這是一個可以很好地擴展的解決方案(t2 中 250k recs 上的 6s)并且可以滿足我的要求。
我無法得到戈登在 Access 中作業的答案。不過好像應該有。而且我懷疑它在 t2 中使用 250k recs 的表現如何。如果我能弄清楚如何讓 Access 接受它,我很想測驗像 Gordon 這樣的解決方案。
有關我所追求的記錄的示例,請參閱問題描述。我只需要結果集中的t2.id。最初并未說明這一點,但我看不出這會如何改變問題陳述或解決方案。我可能錯了。我仍然需要 t3.name,但可以稍后使用 t2.id 檢索它。
但我仍然需要選擇 GROUP'd BY t1.g1, t1.g2的記錄,當所有記錄按t2.dateandtime, t2.id排序時,該記錄排在第一位。或者換句話說,在具有相同 t1.g1 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.dateandtime 和 t2.id 組合到一個文本欄位中,并使用 MIN 來選擇資料/記錄,一旦它被 GROUP'd BY。不需要對我的結果集進行排序,因為t2.date和time的MIN值的記錄,那么t2.id就被選中了!從而滿足我的條件并選擇了正確的記錄。
- 由于我只需要回傳 t2.id 以供進一步處理,我從 #3 中內置的 String 中提取 t2.id 并將其轉換回 Long 資料型別。
這是簡短而簡單的查詢:
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/314253.html
