如何使用 SQL 从一个 table 中找到另一个 table 中的第一个匹配结果?
How to use SQL find first matching result from one table in another table?
假设我有两个 tables:
Customer -
ID | Name | Etc
1 | One |
2 | Two |
3 | Three |
4 | Four |
5 | Five |
... | ... |
Sales -
Customer ID | Date | Amount
5 | 1/20 |
5 | 3/19 | 5
3 | 8/19 | 3
7 | 3/20 | 13
3 | 9/20 | ...
1 | 3/20 | ...
1 | 1/20 | ...
我想做的是编写一个查询来查找每个客户的第一笔销售。我不确定该怎么做。我觉得这是按问题分组的,但我没有找到答案。
编辑:
我觉得我的第一个数据 table 没有完全解释我的问题。 (老实说,直到我编写解决方案时,我才意识到我的问题的这一方面)注意:每次销售有不止一个客户。
Sales -
Sale ID | Customer ID | Date | Amount
1 | 5 | 1/20 |
5 | 5 | 3/19 | 5
8 | 3 | 8/19 | 3
7 | 7 | 3/20 | 13
3 | 4 | 9/20 | ...
2 | 1 | 3/20 | ...
1 | 1 | 1/20 | ...
您可以使用子查询为每个客户的每个销售分配一个行号,按日期升序排序,然后 select 仅第一行:
SELECT "Customer ID", "Date", "Amount"
FROM (
SELECT "Customer ID", "Date", "Amount",
ROW_NUMBER() OVER (PARTITION BY "Customer ID" ORDER BY "Date") AS rn
FROM Sales) s
WHERE rn = 1
Nick 的解决方案可能是最高效的,但如果您想在此处使用 GROUP BY
,您可以这样做:
SELECT
c.ID,
c.Name,
s1.Date,
s1.Amount
FROM Customer c
INNER JOIN Sales s1 ON c.ID = s1."Customer ID"
INNER JOIN
(
SELECT "Customer ID", MIN(Date) AS FirstSaleDate
FROM Sales
GROUP BY "Customer ID"
) s2
ON s1."Customer ID" = s2."Customer ID" AND
s1.Date = s2.FirstSaleDate
ORDER BY
c.ID,
c.Name;
在 Oracle 中,您可以使用 keep
:
select customer_id, min(date) as first_sales_date,
max(amount) keep (dense_rank first order by date asc) as first_amount
from sales
group by customer_id;
假设我有两个 tables:
Customer -
ID | Name | Etc
1 | One |
2 | Two |
3 | Three |
4 | Four |
5 | Five |
... | ... |
Sales -
Customer ID | Date | Amount
5 | 1/20 |
5 | 3/19 | 5
3 | 8/19 | 3
7 | 3/20 | 13
3 | 9/20 | ...
1 | 3/20 | ...
1 | 1/20 | ...
我想做的是编写一个查询来查找每个客户的第一笔销售。我不确定该怎么做。我觉得这是按问题分组的,但我没有找到答案。
编辑: 我觉得我的第一个数据 table 没有完全解释我的问题。 (老实说,直到我编写解决方案时,我才意识到我的问题的这一方面)注意:每次销售有不止一个客户。
Sales -
Sale ID | Customer ID | Date | Amount
1 | 5 | 1/20 |
5 | 5 | 3/19 | 5
8 | 3 | 8/19 | 3
7 | 7 | 3/20 | 13
3 | 4 | 9/20 | ...
2 | 1 | 3/20 | ...
1 | 1 | 1/20 | ...
您可以使用子查询为每个客户的每个销售分配一个行号,按日期升序排序,然后 select 仅第一行:
SELECT "Customer ID", "Date", "Amount"
FROM (
SELECT "Customer ID", "Date", "Amount",
ROW_NUMBER() OVER (PARTITION BY "Customer ID" ORDER BY "Date") AS rn
FROM Sales) s
WHERE rn = 1
Nick 的解决方案可能是最高效的,但如果您想在此处使用 GROUP BY
,您可以这样做:
SELECT
c.ID,
c.Name,
s1.Date,
s1.Amount
FROM Customer c
INNER JOIN Sales s1 ON c.ID = s1."Customer ID"
INNER JOIN
(
SELECT "Customer ID", MIN(Date) AS FirstSaleDate
FROM Sales
GROUP BY "Customer ID"
) s2
ON s1."Customer ID" = s2."Customer ID" AND
s1.Date = s2.FirstSaleDate
ORDER BY
c.ID,
c.Name;
在 Oracle 中,您可以使用 keep
:
select customer_id, min(date) as first_sales_date,
max(amount) keep (dense_rank first order by date asc) as first_amount
from sales
group by customer_id;