编辑:MySQL的:选择默认的行(不是默认值),如果其他行不提供
我已经包括了创建报表和一个小的测试数据集,为您尝试。因此,我已将示例id
更改为2
而不是5
以表示测试数据中现有的id
。
/编辑
我必须保持局部的页面信息为三个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');
的困境:
用检索页面所有活动区域设置我发出以下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编写器块。我会很感激你的帮助。
如果父页面也不适用于特定的语言环境,该怎么办? – 2011-02-13 13:16:14
@ Scrum Meister:好问题!但是假设系统中始终可以使用根页面(parentId IS NULL,即不一定是父页面)。这是一个无法删除的页面。 – 2011-02-13 13:18:31