2009-09-01 2 views
1

누구든지 mySQL 학습을위한 좋은 책을 추천 할 수 있다면 그것은 좋을 것이다. :)MySQL 쿼리에 어떤 유형의 참여가 있습니까? 확실하지 않음

나는

CREATE TABLE `tags` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
`name` varchar(40) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, 
PRIMARY KEY (`id`), 
UNIQUE KEY `name` (`name`) 
) ENGINE=InnoDB AUTO_INCREMENT=190 DEFAULT CHARSET=utf8 


CREATE TABLE `codes_tags` (
`code_id` int(11) unsigned NOT NULL, 
`tag_id` int(11) unsigned NOT NULL, 
KEY `sourcecode_id` (`code_id`), 
KEY `tag_id` (`tag_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

는 내가 뭘하려고 오전 '태그'에서 이름을 선택하고, 'codes_tags'에 얼마나 많은 것을 tag_id의이 두 테이블, 태그, codes_tags이 그 수에 따라 그들을 주문하십시오. 해당 tag_id에 대한 codes_tags에 레코드가 없으면 'count'는 0 또는 NULL (바람직하게는 0)과 같아야합니다.

이것은 내가 지금까지 온 가장 가까운 : 어떻게 생각은 30

을 반환해야 할 때, 그러나 그것은 네 개의 행을 반환, 내가 걸려 일을 할 것 같다

SELECT tags.name, COUNT(codes_tags.tag_id) AS count 
FROM tags 
LEFT JOIN codes_tags ON tags.id = codes_tags.tag_id 
GROUP BY tag_id 
ORDER BY count DESC 
LIMIT 0 , 30 

여기 잘못있는거야? 감사합니다. .

답변

0

COUNT (codes_tags.tag_id)를 SELECT에서 COUNT (*)로 변경하면 NULL도 포함됩니다. null 또는 0 카운트가 누락 된 경우 쿼리가 정상적으로 처리됩니다.

편집 : 두 번째 생각에 LEFT JOIN을 놓쳤습니다. 즉, 코드 태그 테이블의 내용과 관련이 없더라도 모든 태그를 원한다는 뜻입니다. 너가 원하는게 그거야?

나는 아마 다음과 같이 뭔가를 할 것이다 :

SELECT tags.name, COUNT(*) AS count 
FROM tags 
INNER JOIN codes_tags ON tags.id = codes_tags.tag_id 
GROUP BY tags.id 
ORDER BY count(*) DESC 

그것은 태그도 codes_tags에 포함되지 않은 목록에없는 항목 에서 유추 할 수있다. 당신이 원하는 경우, 명시 적으로뿐만 아니라해야 할 일 :

SELECT tags.name, COUNT(*) AS count 
FROM tags 
INNER JOIN codes_tags ON tags.id = codes_tags.tag_id 
GROUP BY tags.id 
UNION 
SELECT tags.name, '0' 
from tags 
where tags.name not in 
    (SELECT tags.name 
    FROM tags 
    INNER JOIN codes_tags ON tags.id = codes_tags.tag_id) 
ORDER BY count(*) DESC 

(나는 순간에 SQL 상자에 액세스 할 수 있으므로 에누리 쿼리를하지 않는 그들은 안된입니다.)

+0

미안하지만 이미 시도해 보았습니다. 반환 값은 조금 이상합니다. 첫 번째 레코드의 카운트는 185이고 그 다음에는 3의 정확한 카운트가 있습니다.하지만 여전히 4 개의 레코드 만 반환합니다. –

+0

두 번째 SQL 쿼리가 정확히 내가했던 것입니다. 그것이 무엇을하는지 설명해 주시겠습니까? –

+0

첫 번째 SELECT는 tags 및 codes_tags 테이블에있는 모든 이름의 이름과 개수를 가져옵니다. UNION은 더 많은 행을 추가하려고한다고 말합니다 (두 쿼리에서 열 유형과 개수가 동일해야 함). 두 번째 SELECT는 첫 번째 SELECT의 해당 항목에 대해서만 이름과 0 (계수를 나타 내기 위해)을 가져옵니다. WHERE 절은 결과를 첫 번째 쿼리에 포함되지 않은 이름으로 제한합니다. –

1

LEFT OUTER JOIN에 좀 더미 데이터와 MySQL을이를 테스트 한 쿼리는 나를 위해 4 개 이상의 행을 반환 것으로 보인다. 나는 당신의 create table 문을 실행하고 다음 문장으로 그것들을 채 웠습니다.

insert into tags (name) values ('java'), ('mysql'), ('php'), ('ruby'), ('.net'), ('python'); 
insert into codes_tags (code_id, tag_id) values (1,194), (2,194), (3,194), (1,191), (2,191), (3,191), (4,191), (5,191), (1,192), (1,195), (1,193); 

해당 데이터에 대한 쿼리를 실행하면 6 개의 행이 반환됩니다. 다음 외래 키를 추가 할 수 있습니다, 당신은 적절한 데이터 무결성을 확인하기 위해,

select count(*) from tags; 
select * from tags limit 10;

또한 그것은 경우를 참조하십시오 더 디버깅이를 돕기 위해 다음과 같은 두 쿼리의 결과를 게시 할 수 있습니다 성공합니까?

alter table codes_tags add foreign key codes_tags_tag_id_key(tag_id) references tags(id);