在 table 每个客户的多张发票中,我想确定每个客户的第一张发票(行)

In a table of multiple invoices per client, I want to identify the first invoice (row) for each client

我试过了,但它没有产生我期望的效果:

SELECT 
       client_id,
       invoice_date,
       invoice_number,
       invoice_value
FROM tblInvoices
WHERE tblInvoices.invoice_date IN
    (SELECT min(tblInvoices.invoice_date)
     FROM tblInvoices
     GROUP BY client_id)
GROUP BY client_id

对于每个单独的客户,您的子查询变得最小 invoice_date,但是客户和他的日期之间的 link 丢失了。

SELECT client_id,
       invoice_date,
       invoice_number,
       invoice_value
FROM tblInvoices
WHERE (client_id, invoice_date) IN ( SELECT client_id, min(invoice_date)
                                     FROM tblInvoices
                                     GROUP BY client_id )

如果某个客户存在多个具有相同最小日期的记录 - 所有记录都将被返回。

我只想使用相关子查询来过滤 table:

select t.*
from tblinvoices t
where t.invoice_date = (
    select min(t1.invoice_date) 
    from tblinvoices t1 
    where t1.client_id = t.client_id
)

此选项通常会在正确的索引到位的情况下产生良好的性能 - 在这里,您需要 (client_id, invoice_date).

上的索引

另一种典型的解决方案是反左连接:

select t.*
from tblinvoices t
left join tblinvoices t1 
    on  t1.client_id = t.client_id
    and t1.invoice_date < t.invoice_date
where t1.client_id is null

您可以通过检查 invoice_date 与使用子查询连接的每个用户的最小值来获取客户及其数据。

SELECT client_id,
       invoice_date,
       invoice_number,
       invoice_value
FROM tblInvoices AS upper_table
WHERE invoice_date IN (
                        SELECT min(invoice_date)
                        FROM tblInvoices
                        WHERE upper_table.client_id=tblInvoices.client_id
                      )

这是一个有多个解决方案的众所周知的问题。这个使用带有内部连接的不相关子查询:

SELECT 
    t.client_id,
    invoice_date,
    invoice_number,
    invoice_value
FROM tblInvoices t
JOIN (
    SELECT client_id, MIN(invoice_date) AS min_invoice_date
    FROM tblInvoices
    GROUP BY client_id
) sq ON t.client_id = sq.client_id AND t.invoice_date = sq.min_invoice_date

但是,如果给定客户的最小发票日期不是唯一的(第 invoice_date 列可能是 DATE 类型;未指定)怎么办?那么上面的 SQL 将为该客户 return 多行。那么我们可能想要 return 具有最小发票日期和最小发票编号的行:

SELECT 
    t.client_id,
    invoice_date,
    invoice_number,
    invoice_value
FROM tblInvoices t
JOIN (
    SELECT t.client_id, MIN(invoice_number) AS min_invoice_number from tblInvoices t JOIN (
       SELECT client_id, MIN(invoice_date) AS min_invoice_date
       FROM tblInvoices
       GROUP BY client_id
    ) sq ON t.client_id = sq.client_id AND t.invoice_date = sq.min_invoice_date
    GROUP BY t.client_id
) sq2 ON /* t.client_id = sq2.client_id AND */ t.invoice_number = sq2.min_invoice_number

我在上述 SQL 中假设 invoice_number 列是唯一键。