关联st_kalk、_artikli与dok表,获取所有商品最新价格的SQL查询需求
解决多表关联获取每个商品最新净价的问题
嘿,别担心,刚开始学SQL遇到这种「按组取最新记录」的问题太正常了!你的需求是关联三张表,给每个id_artikli拿到对应最新datum(日期)的cena_neto(净价)对吧?咱们一步步来修正你的查询,实现返回所有商品最新价格的目标。
问题分析:你的现有查询存在的问题
先看看你当前的查询为什么只能查单个商品:
- 用了
TOP 1,这会限制结果只返回第一条记录,自然只能看到单个商品的数据; GROUP BY id_artikla,cena_neto把cena_neto也加入了分组条件,这会导致同一个商品只要价格不同就会被分成不同组,没法准确拿到最新日期对应的价格;- 关联
_artikli的条件写错了:k.id_artikla=k.id_artikla是恒成立的无意义条件,应该关联两张表的id_artikli字段。
解决方案:用窗口函数获取每个商品的最新记录
处理「每个分组取最新/第一条数据」这类需求,最通用的方法是用ROW_NUMBER()窗口函数,它能给每个分组内的记录按指定规则排序并编号。
完整SQL查询
SELECT a.id_artikli, latest.datum AS 最新日期, latest.cena_neto AS 最新净价 FROM _artikli a LEFT JOIN ( -- 子查询:给每个商品的价格记录按日期倒序编号,最新的记录编号为1 SELECT sk.id_artikli, d.datum, sk.cena_neto, ROW_NUMBER() OVER ( PARTITION BY sk.id_artikli ORDER BY d.datum DESC ) AS record_rank FROM st_kalk sk INNER JOIN dok d ON sk.iddg = d.iddg ) latest ON a.id_artikli = latest.id_artikli WHERE latest.record_rank = 1 -- 只保留每个商品的最新记录 -- 如果_artikli表存在重复的id_artikli,想去重可以添加DISTINCT -- DISTINCT a.id_artikli, latest.datum, latest.cena_neto ORDER BY a.id_artikli;
查询逻辑解释
内层子查询:
- 先关联
st_kalk和dok,拿到每条价格记录对应的日期; - 用
ROW_NUMBER()按id_artikli分组(PARTITION BY sk.id_artikli),每个组内按datum从新到旧排序(ORDER BY d.datum DESC),给每条记录分配一个编号record_rank,最新的那条记录编号为1。
- 先关联
外层查询:
- 将
_artikli和子查询结果做左连接(如果某个商品在_artikli里但没有价格记录,会显示NULL;如果只想要有价格的商品,改成INNER JOIN即可); - 筛选
record_rank = 1的记录,就是每个商品的最新价格和对应日期。
- 将
备选方案(适用于支持TOP WITH TIES的数据库,如SQL Server)
如果你用的是SQL Server这类支持TOP WITH TIES的数据库,也可以用更简洁的写法:
SELECT DISTINCT a.id_artikli, d.datum AS 最新日期, sk.cena_neto AS 最新净价 FROM _artikli a INNER JOIN st_kalk sk ON a.id_artikli = sk.id_artikli INNER JOIN dok d ON sk.iddg = d.iddg ORDER BY ROW_NUMBER() OVER (PARTITION BY a.id_artikli ORDER BY d.datum DESC) OFFSET 0 ROWS FETCH NEXT 1 ROWS WITH TIES;
这种写法利用WITH TIES特性,会返回所有排序后编号为1的记录,也就是每个商品的最新价格。
内容的提问来源于stack exchange,提问作者Dj1999
相关产品推荐
相关产品推荐

