You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL查询用DISTINCT仍返回重复Date字段值的解决方法咨询

问题原因分析
  • 你之前使用DISTINCT无效的原因是:DISTINCT是对查询返回的所有字段的组合值去重,同日期下价格字段值不同时,整行记录的组合值不重复,因此不会被去重。
  • 你尝试的UNION查询本身存在语法错误:UNION要求前后两个子查询返回的字段数量、字段类型完全匹配,你第一个子查询仅返回DATE1个字段,第二个返回4个价格字段,根本无法正常执行。
解决方案

首先修正原SQL里的不规范写法:原WHERE条件中AND Date、AND Open这类写法是判断字段非空非0的简写,建议统一写成字段 IS NOT NULL,逻辑更清晰也避免隐式转换问题。

方案1:MySQL 8.0+ 版本(推荐,性能更优)

使用ROW_NUMBER()窗口函数,按日期分组,按你表中自增主键(假设主键名为id,如果有其他表示插入顺序的字段替换即可)排序取每组第一条:

SELECT Date, Open, High, Low, Close
FROM (
    SELECT 
        Date, Open, High, Low, Close,
        ROW_NUMBER() OVER (PARTITION BY Date ORDER BY id ASC) AS rn
    FROM symbolsv2
    WHERE ticker=? 
    AND `intval`=? 
    AND Date>=? 
    AND Date IS NOT NULL
    AND Open IS NOT NULL
    AND High IS NOT NULL
    AND Low IS NOT NULL
    AND Close IS NOT NULL
) AS t
WHERE rn = 1
ORDER BY Date ASC

把你PHP里prepare的SQL替换成上面的即可。

方案2:MySQL 5.x 版本(兼容老版本)

使用子查询匹配每个日期对应的最早插入记录的主键:

SELECT Date, Open, High, Low, Close
FROM symbolsv2 s
INNER JOIN (
    SELECT MIN(id) AS first_id
    FROM symbolsv2
    WHERE ticker=? 
    AND `intval`=? 
    AND Date>=? 
    AND Date IS NOT NULL
    AND Open IS NOT NULL
    AND High IS NOT NULL
    AND Low IS NOT NULL
    AND Close IS NOT NULL
    GROUP BY Date
) AS t ON s.id = t.first_id
ORDER BY s.Date ASC

注意:如果你的表没有自增主键id,可以把ORDER BY id ASC替换为你能判断记录插入先后的字段,比如爬虫抓取时间字段,如果没有时间字段也可以直接按价格字段排序,只要符合你“第一条”的定义即可。

(可选)直接删除表中的重复数据

如果你需要永久删除表中同日期的冗余重复记录,执行以下SQL即可(执行前建议先备份数据):

DELETE s1
FROM symbolsv2 s1
JOIN symbolsv2 s2 
  ON s1.ticker = s2.ticker 
  AND s1.intval = s2.intval 
  AND s1.Date = s2.Date 
  AND s1.id > s2.id;

执行后每个日期仅会保留id最小的第一条记录,后续查询就不需要再做去重处理了。

内容的提问来源于stack exchange,提问作者user17153595

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 15:24:08