代码之家  ›  专栏  ›  技术社区  ›  Nyranith

从值子集中选择多个最小值

  •  0
  • Nyranith  · 技术社区  · 8 年前

    问题是我想选择每个域并获得每个域的所有访问权限。 所以问题是从多个子集中选择一个最小值。知道怎么做吗?

    所以我尝试过:

    SELECT r.* FROM `domain` as d 
    INNER JOIN ( 
        SELECT domain, min(`update`) FROM `right` 
        ) r ON d.name = r.domain;
    

    这给了我一个结果:

    域最小值( update )

    另一个测试为真

    我想要的是:

    域最小值( 使现代化 )

    另一个测试为真

    某些名称正确

    Sql小提琴连接: http://sqlfiddle.com/#!9/841183

    导出带有测试值的sql表:

    CREATE TABLE `domain` (
      `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
      `displayName` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
      `description` varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL,
      `created_at` timestamp NULL DEFAULT NULL,
      `updated_at` timestamp NULL DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    
    ALTER TABLE `domain`
      ADD PRIMARY KEY (`name`);
    
    CREATE TABLE `groups` (
      `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
      `created_by` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
      `created_at` timestamp NULL DEFAULT NULL,
      `updated_at` timestamp NULL DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    
    ALTER TABLE `groups`
      ADD PRIMARY KEY (`name`),
      ADD KEY `groups_created_by_foreign` (`created_by`);
    
    
    CREATE TABLE `right` (
      `domain` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
      `group` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
      `read` tinyint(1) NOT NULL,
      `update` tinyint(1) NOT NULL,
      `create` tinyint(1) NOT NULL,
      `delete` tinyint(1) NOT NULL,
      `modify` tinyint(1) NOT NULL,
      `execute` tinyint(1) NOT NULL,
      `created_by` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
      `created_at` timestamp NULL DEFAULT NULL,
      `updated_at` timestamp NULL DEFAULT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    
    ALTER TABLE `right`
      ADD PRIMARY KEY (`domain`,`group`),
      ADD KEY `right_group_foreign` (`group`),
      ADD KEY `right_created_by_foreign` (`created_by`);
    
    
    INSERT INTO `domain` (`name`, `displayName`, `description`, `created_at`, `updated_at`) VALUES
    ('Another test', 'Another test', NULL, '2016-08-22 12:05:06', '2016-08-22 12:05:06'),
    ('Some Name', 'Some Name', NULL, '2016-08-19 03:57:00', '2016-08-19 03:57:00');
    
    
    INSERT INTO `groups` (`name`, `created_by`, `created_at`, `updated_at`) VALUES
    ('groupTest', NULL, '2016-08-22 12:06:48', '2016-08-22 12:06:48'),
    ('testGroup', NULL, '2016-08-19 03:56:35', '2016-08-19 03:56:35');
    
    
    INSERT INTO `right` (`domain`, `group`, `read`, `update`, `create`, `delete`, `modify`, `execute`, `created_by`, `created_at`, `updated_at`) VALUES
    ('Another test', 'groupTest', 0, 1, 0, 0, 0, 0, NULL, '2016-08-22 12:07:02', '2016-08-22 12:07:02'),
    ('Another test', 'TestGroup', 1, 1, 0, 0, 0, 0, NULL, '2016-08-22 12:06:04', '2016-08-22 12:06:04'),
    ('Some Name', 'TestGroup', 0, 1, 0, 0, 0, 0, NULL, '2016-08-19 03:57:05', '2016-08-19 03:57:05');
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Shadow    8 年前

    您需要使用 group by 子句以按组获取最小值。这里所说的组是指域:

    select d.name, min(`update`) as min_update_right
    from domain d
    inner join `right` r on d.name = r.domain
    group by d.name
    

    如果希望域表中的其他字段出现在选择列表中,那么还需要将这些字段添加到分组依据列表中。

    然而,我会考虑使用位图(或者在MySQL中 set 数据类型),而不是多个字段来存储访问权限。简单的按位操作可以为您提供对域的总体访问权限。