Коррелированные подзапросы в MySql - как сначала оценить внешний запрос? - PullRequest
1 голос
/ 11 июня 2009

У меня проблемы с подзапросами в MySql. У меня есть таблица, содержащая группы пользователей. Столбцы - это id, name и свойства с комментарием, описывающим каждую строку: (Идентификатор INT, Имя VARCHAR, все остальные TINYINT (1) (логическое значение)

ID   |   Name   |   login   |   post   |   manage
 1     user           1           0           0
 2     poster         1           1           0
 3     admin          1           1           1

Моя цель состоит в том, чтобы иметь возможность перечислить свойства группы пользователей (логин, запись и управление выше) и количество групп пользователей, которые имеют каждое свойство (3, 2 и 1 соответственно).

Этот запрос работает (но, очевидно, каждый раз учитывает столбец входа в систему):

SELECT @colname:=cols.column_name,cols.column_comment,
  (SELECT COUNT(*) FROM db.usergroups WHERE login=1) AS num_users
FROM information_schema.columns AS cols 
WHERE TABLE_SCHEMA='db' AND TABLE_NAME='usergroups' AND column_type='tinyint(1)';

Это не работает (num_users всегда 0)

SELECT @colname:=cols.column_name,cols.column_comment,
  (SELECT COUNT(*) FROM db.usergroups WHERE cols.column_name=1) AS num_users
FROM information_schema.columns AS cols 
WHERE TABLE_SCHEMA='db' AND TABLE_NAME='usergroups' AND column_type='tinyint(1)';

Это также (num_users всегда 0)

SELECT @colname:=cols.column_name,cols.column_comment,
  (SELECT COUNT(*) FROM db.usergroups WHERE @colname=1) AS num_users
FROM information_schema.columns AS cols 
WHERE TABLE_SCHEMA='db' AND TABLE_NAME='usergroups' AND column_type='tinyint(1)';

Есть ли способ заставить это работать? То есть - сначала оценить внешнее утверждение?

-

Большое спасибо за любую помощь!

/ Victor

Ответы [ 2 ]

1 голос
/ 11 июня 2009

Если я правильно понимаю вашу проблему, я думаю, что это может сделать то, что вам нужно:

select
  sum(login) as Num_Login_Groups,
  sum(post) as Num_Post_Groups,
  sum(manage) as Num_Manage_Groups
from db.usergroups;

В качестве альтернативы, если вам действительно нужно, чтобы 'login', 'post' и 'manage' отображались в той же строке, что и число групп с этой привилегией, вы можете сделать это:

select 'login' as Property, sum(login) as Count from db.usergroups
union
select 'post' as Property, sum(post) as Count from db.usergroups
union
select 'manage' as Property, sum(manage) as Count from db.usergroups;

Я предполагаю, что это единственные три свойства, которые будет иметь ваша таблица. Если вам нужен расширяемый набор привилегий для каждой группы пользователей, я бы предложил хранить их в отдельной таблице с одной строкой для каждого применимого сочетания пользовательских и привилегий.

Вы также можете рассмотреть возможность использования Name в качестве первичного ключа таблицы, поскольку она более интуитивна и, вероятно, в любом случае должна быть уникальной.

0 голосов
/ 11 июня 2009

Это действительно не способ использовать реляционную базу данных. Вы могли бы , вероятно, сделать это, используя подготовленные заявления ...

PREPARE stmt FROM 'SELECT COUNT(*) FROM db.usergroups WHERE ' + col_name + '=1';
-- Execute statement etc...

Но реальный способ сделать это динамически - разделить столбцы на строки (то есть иметь другую таблицу с именем db.permissiontypes или что-то еще, а затем объединить ее с db.usergroups.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...