2009-06-11 6 views
1

MySql의 하위 쿼리에 문제가 있습니다. 사용자 그룹이 포함 된 테이블이 있습니다. (이드 INT, 이름 VARCHAR, 다른 모든 TINYINT (1) (부울)MySql에서 상관 관계가있는 하위 쿼리 - 먼저 외부 쿼리를 평가하는 방법?

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

내 목표는 할 수있을 것입니다 수 있습니다 : 열은 ID, 이름 및 각 행을 설명하는 주석과 재산입니다 사용자 그룹 속성 목록 (로그인, 게시 이상 관리) 및 각 속성 (각각 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 is al 방법 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)'; 

는이 작업을 얻을 수있는 방법이 항상 존재하지 않습니다이? 즉, 외부 문장을 먼저 평가하는 것입니까?

-

어떤 도움을 주셔서 감사합니다.

/빅터

답변

1

내가 제대로 문제를 이해한다면, 나는 이것이 당신이 필요 할 것 같아요 :

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

또는 당신이 정말로 '로그인', '후'와 '관리'를해야하는 경우 그 권한이있는 그룹의 수와 같은 행에 표시, 당신이 할 수 있습니다 :

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

감사합니다.하지만 행을 세는 것은 실제로 문제가 아닙니다. 문제는 information_schema (설명 또는 "예쁜 이름"으로 사용됨)에서 주석을 가져 와야하고 동일한 쿼리에서 카운트가 추가되었습니다. 어쨌든 고마워! – Victor

0

이것은 실제로 관계형 데이터베이스를 사용하는 방법이 아닙니다. 당신은 아마 ... 그것은 준비된 문을 사용하여

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

할 수 그러나 동적으로이 작업을 수행하는 실제 방법 (행으로 열을 분리하는 것입니다 즉, 다른 테이블이 db.permissiontypes 또는 이것 저것라고 한 다음 db.usergroups로 가입 .)

+0

"그게 진짜 방법이 아니에요 ..."- 글쎄요 ... 저는 보통이 말에 동의 할 것입니다 (그리고 여러분이 제안한 것처럼 여분의 테이블을 만드십시오). 특히 열 이름 이외의 정보를 추가 할 수있는 가능성을 제공합니다. 및 열 주석. 하지만이 경우 (이름과 설명이 모두 필요한만큼) 열로 놓으면 하나의 조인을 생략 할 수 있으므로 정상적인 작동 속도가 조금 향상됩니다. "더 나은"방법으로 "usertable JOIN usergroups usergroupproperties에 가입하십시오"이제 "usertable JOIN usergroups"이면 충분합니다. 그리고 .. 사장님이 요청했습니다! ;-) – Victor

+0

Hmmm ... 구조가 돌이 변하지 않고 변경 될 수 있다고 주장 할 수는 없지만 성능면에서 볼 때 관계형 데이터베이스에서 비 관계형 방법. 이 경우 어쨌든. 내부 최적화 덕분에 다른 테이블을 동적 SQL보다 빠를 수 있습니다. – Blixt

+0

흠 ... 정말 이상하게 들리는군요 ... 확실합니까? 나는 우리가 여기에서 토론하고있는 종류의 질의는 물론 느릴 것이다. 그러나 보통 (관리자 페이지에 기본적으로 접근하지 않을 때) 필요한 유일한 정보는 user + group + group 속성이다. (이것은 두 테이블의 조인을 의미한다. 각 표에서 행). 그렇지 않으면 결과는 세 개의 테이블에서 조인되어야합니다 (각각에서 하나의 행을 페치). 물론 그 차이는 클 수는 없지만 3 개의 테이블로는 더 빠를 수는 없습니다. 맞습니까? - 후자의 경우 - 성능 이점을 얻으려면 외래 키를 명시 적으로 지정해야합니까? – Victor