edit:
Я включил операторы создания и небольшой набор тестовых данных, которые вы можете попробовать.Поэтому я изменил пример id
на 2
вместо 5
для представления существующего id
в данных испытаний.
/ edit
У меня есть три таблицы MySQL для хранения информации о локализованной странице:
CREATE TABLE `locale` (
`languageCode` char(3) NOT NULL,
`regionCode` char(3) NOT NULL default 'ZZ',
`isActive` enum('yes','no') NOT NULL default 'no',
PRIMARY KEY (`languageCode`,`regionCode`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `page` (
`id` int(10) unsigned NOT NULL auto_increment,
`parentId` int(10) unsigned default NULL,
PRIMARY KEY (`id`),
KEY `FK_page_page_1` (`parentId`),
CONSTRAINT `FK_page_page_1` FOREIGN KEY (`parentId`) REFERENCES `page` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `pageInfo` (
`pageId` int(10) unsigned NOT NULL,
`languageCode` char(3) NOT NULL,
`regionCode` char(3) NOT NULL default 'ZZ',
PRIMARY KEY (`pageId`,`languageCode`,`regionCode`),
KEY `FK_pageInfo_locale_1` (`languageCode`,`regionCode`),
KEY `FK_pageInfo_page_1` (`pageId`),
CONSTRAINT `FK_pageInfo_locale_1` FOREIGN KEY (`languageCode`, `regionCode`) REFERENCES `locale` (`languageCode`, `regionCode`) ON DELETE CASCADE,
CONSTRAINT `FK_pageInfo_page_1` FOREIGN KEY (`pageId`) REFERENCES `page` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
А вот некоторые тестовые данные:
/* locale */
INSERT INTO `locale` (languageCode,regionCode,isActive) VALUES ('de','ZZ','yes');
INSERT INTO `locale` (languageCode,regionCode,isActive) VALUES ('en','ZZ','yes');
INSERT INTO `locale` (languageCode,regionCode,isActive) VALUES ('nl','ZZ','yes');
/* page */
INSERT INTO `page` (id,parentId) VALUES (1,NULL);
INSERT INTO `page` (id,parentId) VALUES (2,1);
/* pageInfo */
INSERT INTO `pageInfo` (pageId,languageCode,regionCode) VALUES (1,'de','ZZ');
INSERT INTO `pageInfo` (pageId,languageCode,regionCode) VALUES (1,'en','ZZ');
INSERT INTO `pageInfo` (pageId,languageCode,regionCode) VALUES (1,'nl','ZZ');
INSERT INTO `pageInfo` (pageId,languageCode,regionCode) VALUES (2,'en','ZZ');
INSERT INTO `pageInfo` (pageId,languageCode,regionCode) VALUES (2,'nl','ZZ');
Дилемма:
Чтобы получить страницы с id 2
всех активных языковых стандартов, я выполняю следующий оператор SQL:
SELECT
p.*, pi.languageCode, pi.regionCode
FROM
page AS p
INNER JOIN pageInfo AS pi
ON pi.pageId = p.id
INNER JOIN locale AS l
ON l.languageCode = pi.languageCode AND l.regionCode = pi.regionCode
WHERE
(p.id = '2')
AND (l.isActive = 'yes')
Как бы я изменил этот оператор, чтобы, если id 2
недоступно для конкретной языковой системы,он автоматически возвращается на корневую страницу для этой локали (то есть: где page.parentId IS NULL
)?Моя цель состоит в том, чтобы MySQL дал мне один, но не оба, для активных локалей.
Я пытался:
WHERE
(p.id = '2' OR (p.parentId IS NULL))
Но, конечно, это дает мне две записи для локалейкоторые на самом деле имеют id 2
также.Я почти уверен, что это возможно (либо с UNION
, вложенными выборками, либо с дублирующим соединением на странице), но здесь у меня есть блок писателей всего SQL.Буду признателен за вашу помощь.