Search Console. Your queries are all there, with impressions, clicks and position, going back sixteen months. Google drops rare queries so no single user becomes identifiable, which is why your query totals never add up to your traffic totals.
Search Console linked to GA4. Admin, Product links, Search Console. You get two reports that put the query next to on-site behaviour. Fine for a quick look, too coarse for analysis.
The bulk data export to BigQuery. This is the real answer once you pass a thousand queries a day. Search Console then writes every query, page, country and device combination to your own dataset each day, without the row limit the interface imposes. Turn it on under Settings, Bulk data export.
SELECT query, SUM(clicks) AS clicks, SUM(impressions) AS impressions
FROM `my-project.searchconsole.searchdata_url_impression`
WHERE data_date BETWEEN DATE_SUB(CURRENT_DATE(), INTERVAL 28 DAY) AND CURRENT_DATE()
AND url = 'https://yoursite.com/a-page/'
GROUP BY query
ORDER BY clicks DESC
Google Ads. Paid search still has its search terms report, which shows what you actually appeared for rather than what you bid on.