Неявное соединение, возвращаемое, когда правое соединение пусто - PullRequest
1 голос
/ 08 марта 2011

У меня есть две таблицы:

contactGroups cg и contactGroupLink cgl.

CREATE TABLE `contactgroups` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `account` int(11) DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL,
  `description` text,
  `dateCreated` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1

CREATE TABLE `contactgrouplink` (
  `groupId` int(11) NOT NULL,
  `ContactId` int(11) NOT NULL,
  PRIMARY KEY (`groupId`,`ContactId`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

Если контакт находится в группе, то запись заносится в таблицу cgl с contactId и groupId.

Это все отлично работает.

Я хочу сделать запрос, который получает всю информацию для всех групп из таблицы cg, где account = 1.

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

Я использую

SELECT
  cg.id AS id,
  NAME,
  description,
  dateCreated,
  COUNT(*) AS number
FROM 
  contactgroups cg,
  contactgrouplink cgl
WHERE 
  cg.account = 1
AND 
  cg.id = cgl.groupId
GROUP BY
  cg.id

Прекрасно работает , пока существует хотя бы один контакт для группы . в противном случае группа не возвращается.

Что я должен сделать с этим запросом, чтобы он возвращал все группы?

Ответы [ 2 ]

1 голос
/ 08 марта 2011

Используйте LEFT JOIN, и IFNULL () предотвратит нулевые значения при условии, что в таблице псевдонимов cgl нет таких совпадающих записей

SELECT   
      cg.id AS id,   
      NAME,   
      description,   
      dateCreated,   
      IFNULL( COUNT(*), 0 ) AS number 
   FROM    
      contactgroups cg
         LEFT JOIN contactgrouplink cgl 
            ON cg.id = cgl.groupID
   WHERE    
      cg.account = 1
1 голос
/ 08 марта 2011

Используйте LEFT JOIN для возврата строки для каждого члена левой таблицы, даже если в правой таблице нет соответствующей строки.

Другими словами, используйте этот запрос:

SELECT
  cg.id AS id,
  NAME,
  description,
  dateCreated,
  COUNT(cgl.groupId) AS number
FROM contactgroups AS cg
LEFT JOIN contactgrouplink AS cgl
ON cg.id = cgl.groupId
WHERE cg.account = 1

Конечно, это вернет только все группы, где cg.account = 1, но я предполагаю, что это то, что вы имели в виду под "всеми группами".(Если вам действительно нужны все группы, пропустите предложение WHERE).

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