Mysql:具有最小值的行并根据大小写优先考虑条件

标签 mysql join having

我有两个表,第一个表是: 文档 和另一张 table : doc_val

doc_id 作为表 docs 的外键

我需要从 doc_val 中获取 docs 列表(包括 valtypecriteria ) 匹配某些条件,例如:doc_val.criteria = 'L' and docs.rev = 1

在获取此文档列表时,我还需要确保给定 doc_iddoc_val.val 是最小值。并且还要确保 doc_val.type = 'D',假设存在 doc_val.type = 'D' 否则我们应该简单地获取 doc_val 对于给定的 doc_id,它具有最小的 doc_val.val

CREATE TABLE IF NOT EXISTS `docs` (
  `id` int(6) unsigned NOT NULL,
  `rev` int(3) unsigned NOT NULL,
  `content` varchar(200) NOT NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `doc_val` (
  `id` int(6) unsigned NOT NULL,
  `doc_id` int(6) unsigned NOT NULL,
  `val` int(3) unsigned NOT NULL,
  `type` varchar(2) NOT NULL,
  `criteria` varchar(2) NOT NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;

INSERT INTO `docs` (`id`, `rev`, `content`) VALUES
  ('1', '1', 'The earth is flat'),
  ('2', '1', 'One hundred angels can dance on the head of a pin'),
  ('3', '1', 'The earth is flat and rests on a bull\'s horn'),
  ('4', '4', 'The earth is like a ball.');

INSERT INTO `doc_val` (`id`, `doc_id`, `val`, `type`, `criteria`) VALUES
  ('1', '1', 100, 'D', 'L'),
  ('2', '1', 101, 'D', 'L'),
  ('3', '1', 80, 'H', 'L'),
  ('4', '2', 10, 'H', 'S'),
  ('5', '2', 90, 'H', 'L'),
  ('6', '3', 100, 'D', 'L'),
  ('7', '3', 100, 'D', 'L');

对于此查询,如果我将 b.type = 'D' 简单地作为 where 条件的一部分,我将丢失所有类型不为 D 的文档。

SELECT a.id, a.rev, a.content, b.val, b.type, b.criteria
FROM `docs` a
  JOIN `doc_val` b ON b.doc_id = a.id
  WHERE a.`rev` = 1 and b.type = 'D' and b.criteria = 'L'      
GROUP BY `a`.`id`
HAVING min(b.`val`)

enter image description here

如果我们根本不将 type=D 视为条件,则此条件的输出有点有效,但是,

SELECT a.id, a.rev, a.content, b.val, b.type, b.criteria
FROM `docs` a
  JOIN `doc_val` b ON b.doc_id = a.id
  WHERE a.`rev` = 1 and b.criteria = 'L'      
GROUP BY `a`.`id`
HAVING min(b.`val`)

最终预期输出:

enter image description here

但从技术上讲,如果没有 type=D 作为条件,我应该会收到 doc.id = 1 的输出:

enter image description here

  1. 所以我可能在使用 HAVING 时做错了任何方向都会有帮助。

  2. 是否可以将 doc_val.type 设置为 doc_val.type = D 的优先级,这样当 type = D 的行> 它优先,如果它不存在,只取一个最小值而不考虑type?

最佳答案

你可以试试下面-

DEMO

SELECT 
    *
FROM
    (SELECT 
        a.id, a.rev, a.content, MIN(b.val) val, b.type, b.criteria
    FROM
        `docs` a
    JOIN `doc_val` b ON b.doc_id = a.id
    WHERE
        a.`rev` = 1 AND b.criteria = 'L'
    GROUP BY a.id , a.rev , a.content , b.type , b.criteria) A
WHERE
    val IN (SELECT 
            MAX(val)
        FROM
            (SELECT 
                a.id, a.rev, a.content, MIN(b.val) val, b.type, b.criteria
            FROM
                `docs` a
            JOIN `doc_val` b ON b.doc_id = a.id
            WHERE
                a.`rev` = 1 AND b.criteria = 'L'
            GROUP BY a.id , a.rev , a.content , b.type , b.criteria) B
        WHERE
            A.content = B.content)

输出:

id  rev content                                            val   type  criteria                  
1   1   The earth is flat                                   100  D     L
2   1   One hundred angels can dance on the head of a pin   90   H     L
3   1   The earth is flat and rests on a bull's horn        100  D     L

关于Mysql:具有最小值的行并根据大小写优先考虑条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56073881/

相关文章:

php - MySQL 错误 - InnoDB 不工作并且服务器立即关闭

php - 使用单个查询更新多行

mysql - 使用 AES 加密密码 MySQL 对用户进行身份验证

sql - 使用 join 更新多行速度非常慢

sql - 如何在特定 SQL 案例中将 SELECT 与 GROUP BY 和 HAVING 一起使用

MySQL where 条件与 2 个值相交(逗号分隔)

MySQL:使用 "ON"匹配不精确的值

具有 ENUM 的 MAX() 值的 MYSQL JOIN

MySQL 多对多连接 AND 查询不起作用

sql - 如何编写 SQLite 代码以显示指定代码及其来自 group_concat 函数的关联代码?