【问题标题】:MySQL get just one row duplicated result on selectMySQL在选择时只得到一行重复的结果
【发布时间】:2020-12-28 04:07:36
【问题描述】:

我有以下选择查询。当存在“ES”行时,我想避免获得重复的“EN”行。喜欢 ES 而不是 EN。

SELECT s.soft_id,s.groupby,s.packageid,s.name,s.area,l.min,GROUP_CONCAT(DISTINCT JSON_ARRAY(s.version,s.detailid,s.filesize,s.updatetime)) versions
FROM software s
INNER JOIN langs l ON s.lang_id=l.lang_id
INNER JOIN devices_type t ON (s.familylock_id=t.familylock_id OR (s.familylock_id=0 AND s.devicelock_id=t.device_type_id))
INNER JOIN devices d ON t.device_type_id=d.device_type_id
INNER JOIN users u ON d.user_id=u.user_id
WHERE s.groupby IN(1,2,3)
AND u.token="abc"
AND d.serialno="123456789" 
AND l.min IN("ES","EN")
GROUP BY s.soft_id,s.groupby,s.packageid,s.name,s.area,l.min ORDER BY s.name ASC

这是示例结果。我想摆脱 AUDI 和 AUTOSEARCH "EN" 行。

Image

【问题讨论】:

  • 您通常 GROUP BY 与您选择的列相同,但那些作为设置函数的参数的列除外。
  • 没错!试一试,看看你是否得到了预期的结果。
  • 您误用了 MySQL 臭名昭著的非标准扩展 GROUP BY。请阅读这个。 dev.mysql.com/doc/refman/8.0/en/group-by-handling.html

标签: mysql sql arrays join select


【解决方案1】:

以下有帮助吗?我无法验证脚本,因为我没有示例数据,但下面的想法应该可以帮助您设置优先级。

DB Fiddle

WITH preference  AS
   (
      SELECT s.*, row_number() OVER (PARTITION BY s.soft_id
      ORDER BY s.packageid,
         CASE
            WHEN l.min = 'ES'
            THEN 'A'
            ELSE 'B'
         END)  priority
      FROM software s
INNER JOIN langs l ON s.lang_id=l.lang_id
WHERE l.min IN("ES","EN")
   )
SELECT  *
FROM preference
WHERE priority = 1;

【讨论】:

    【解决方案2】:

    如果存在带有l.min = 'ES' 的行,您需要更改WHERE 条件以排除带有l.min = 'EN' 的行。您可以使用NOT EXISTS 子句来执行此操作;改变

    AND l.min IN("ES","EN")
    

    条件

    AND (l.min = 'ES' OR
         l.min = 'EN' AND NOT EXISTS (SELECT * 
                                      FROM software s2
                                      JOIN langs l2 ON l2.lang_id = s2.lang_id
                                      WHERE s2.soft_id = s.soft_id 
                                        AND l2.min = 'ES')
         )
    

    小样demo on SQLFiddle

    【讨论】:

    • 再见@Nick。我更换了它,但它不工作,同样的结果。我认为方式很接近,但子选择不应该是正确的。 langs 表总是存储所有可用的语言。但软件是应该搜索的地方。如果我的初始查询中有两行重复,则只获取首选的“ES”
    • @Febian 这就是子查询中的l2.lang_id = s.lang_id 的用途,它会将返回的值限制为与特定软件行匹配的值。
    • 上一条评论中有一个链接,您可以在其中使用建议的 mod 运行查询,但结果与我的初始查询相同
    • @Febian 很抱歉没有回复,我已经离开办公桌了。我已更正查询,请查看我的修改。
    • 谢谢。查询有效。但在 localhost 上需要 1 秒,而第一个查询需要 0.014 秒或 0.00 秒。我不应该使用它吗?你有其他想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 2013-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多