我正在尝试将一个客户表与一个销售表结合在一起,在这里我显示数据库中所有客户的列表以及该客户可能在销售表中进行的任何有偿销售。现在,客户可以在销售表中具有多个销售行。 这是一个在销售表中有多个销售的客户的销售记录示例
在提取此记录时,我只想获取q(paid_mountamount)> 0的最大值(q_saledatetime)。 该客户上次向我们付款的时间显示 。因此,在这种情况下,我想为该客户支付的第二行的价格为8.90。 如果客户在销售表中没有记录,请以任何一种方式在列表中显示其姓名/详细信息。
我目前的失败是如何在“已付款金额+最高日期”列中添加where子句。
尝试A
select DISTINCT ON (q_customer.q_code)
q_customer.q_code, q_customer.q_name, -- customer info
MAX(q_saleheader.q_saledatetime) AS latestDate, q_saleheader.q_paidamount -- saleheader info
FROM q_customer
LEFT JOIN q_saleheader ON (q_customer.q_code = q_saleheader.q_customercode)
group by q_customer.q_code, q_customer.q_name , q_saleheader.q_saledatetime, q_saleheader.q_paidamount
order by q_customer.q_code ASC
这将导致
因此,对于Fred Blogg来说,它是从第4行而不是第2行获取详细信息, (第一张图片) 。由于目前没有q_paidamount的规则
ATTEMPT B
SELECT
customer.q_code, customer.q_name, -- customer info
sale.q_saledatetime, sale.q_paidamount -- sale info
FROM q_customer customer
LEFT JOIN (SELECT * FROM q_saleheader WHERE q_saledatetime =
(SELECT MAX(q_saledatetime) FROM q_saleheader b1 where q_paidamount > 0 ))
sale ON sale.q_customercode = customer.q_code
这将导致
这似乎根本没有从销售表中获取任何信息。
更新:
仔细查看我的第一次尝试后,我修改了该语句,并提出了此解决方案,该解决方案可实现与Michal的回答相同的结果。我只是想知道以下方法是否存在任何陷阱或性能劣势。
select DISTINCT ON (q_customer.q_code)
q_customer.q_code, q_customer.q_name, -- customer info
q_saleheader.q_saledatetime, q_saleheader.q_paidamount -- saleheader info
FROM q_customer
LEFT JOIN q_saleheader ON (q_customer.q_code = q_saleheader.q_customercode AND
q_saleheader.q_paidamount > 0 )
group by q_customer.q_code, q_customer.q_name , q_saleheader.q_saledatetime,
q_saleheader.q_paidamount
order by q_customer.q_code ASC, q_saleheader.q_saledatetime DESC
主要更改是在联接上添加AND q_saleheader.q_paidamount> 0和q_saleheader.q_saledatetime DESC,以确保获取该相关数据的第一行。如前所述,Michal的答案和此解决方案均能达到相同的结果。只是对两种方式的陷阱感到好奇。
答案 0 :(得分:2)
尝试此查询:
SELECT c.q_code,
c.q_name,
CASE WHEN q_saledatetime <> '1900-01-01 00:00:00.000' THEN q_saledatetime END q_saledatetime,
q_paidamount
FROM (
SELECT c.q_code,
c.q_name,
coalesce(s.q_saledatetime, '1900-01-01 00:00:00.000') q_saledatetime, --it will indicate customer with no data
s.q_paidamount,
ROW_NUMBER() OVER (PARTITION BY c.q_code ORDER BY COALESCE(s.q_saledatetime, '1900-01-01') DESC) rn
FROM q_customer c
LEFT JOIN (SELECT q_saledatetime,
q_paidamount
FROM q_saleheader
WHERE q_paidamount > 0) s
ON c.q_code = s.q_customercode
) c WHERE rn = 1