2016-08-23 1 views
0

Je crée un système d'accès. Le système d'accès est basé sur le fait qu'un utilisateur peut être membre de plusieurs groupes, le domaine est celui où l'utilisateur demande l'accès. Par exemple, un utilisateur peut être membre de deux groupes, ces deux groupes peuvent avoir accès au domaine et l'utilisateur peut être membre du domaine. Je veux que le droit d'accès le plus bas soit valide, disons que vous êtes ajouté à un groupe qui a un droit inférieur dans ce domaine, ce droit doit précéder l'autre droit.Sélection de plusieurs valeurs min à partir du sous-ensemble de valeurs

Le problème est que je veux sélectionner chaque domaine et obtenir tous les droits d'accès pour chaque domaine. Le problème est donc de sélectionner une valeur min parmi plusieurs sous-ensembles. Vous avez une idée de comment faire cela?

J'ai donc essayé:

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

Cela me donne le résultat:

domaine min (update)

Un autre test vrai

Ce que je veux:

domaine min (update)

Un autre test vrai

Certains vrai nom

lien violon Sql: http://sqlfiddle.com/#!9/841183

Export de la table sql avec des valeurs de test:

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'); 

Répondre

1

Vous devez utiliser la clause group by pour obtenir la mini valeurs mères par groupes. Par groupes ici, je veux dire les domaines:

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 

Si vous voulez des champs supplémentaires à partir de la table de domaine pour être présent dans la liste de sélection, vous devez ajouter ces champs au groupe par liste.

Cependant, je envisagerais d'utiliser un bitmap (ou en MySQL le type de données set) au lieu de plusieurs champs pour stocker les droits d'accès. Les opérations au niveau du bit simples peuvent vous donner le droit d'accès global à un domaine.