我有一个pdo预处理语句,我想在我的数据库中创建一个视图。 "问题"是它需要一个参数。
我从this answer获取灵感,但我似乎无法让它正常工作。使用原始语句,我得到了所有相关的文章,但是下面的函数/视图示例返回所有文章,无论我将@ p1设置为。
我原来的陈述:
SELECT DISTINCT a.articleTitle, a.articlePermalink
FROM articles a
JOIN articleKeywords ak ON a.idarticles = ak.articleId
JOIN articleKeywords ak2 ON ak.keywordId = ak2.keywordId
AND ak2.articleId = :articleId
AND NOT (a.idarticles = :articleId);
其中:articleId
是通过PHP给出的参数。
我创建了一个返回整数的函数:
CREATE FUNCTION p1() RETURNS INTEGER DETERMINISTIC NO SQL RETURN @p1;
我的观点:
CREATE VIEW `view_articleRelated` AS
SELECT DISTINCT a.articleTitle, a.articlePermalink
FROM articles a
JOIN articleKeywords ak ON a.idarticles = ak.articleId
JOIN articleKeywords ak2 ON ak.keywordId = ak2.keywordId
AND ak2.articleId = p1()
AND NOT (a.idarticles = p1());
最后,使用p1()
:
SELECT s.* FROM (SELECT @p1:=123 p) foo, view_articleRelated s;
答案 0 :(得分:1)
在我的第一个答案中,示例代码中存在一些拼写错误和其他一些问题。
我从查询中涉及的ERD创建了三个表:
DROP TABLE IF EXISTS `articles`;
CREATE TABLE `articles` (
`idarticles` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
`articleTitle` VARCHAR(60) NULL,
`articlePermalink` VARCHAR(60) NULL,
`articleBody` TEXT NULL,
`articleAuthor` INT(10) NULL,
`createdAt` DATETIME NULL,
`updatedAt` DATETIME NULL,
PRIMARY KEY (`idarticles`),
KEY `idx_articles1` (`articleTitle`)
)
ENGINE=MyISAM
AUTO_INCREMENT=1
DEFAULT CHARSET=utf8
COLLATE=utf8_unicode_ci
COMMENT 'List of Articles';
DROP TABLE IF EXISTS `articleKeywords`;
CREATE TABLE `articleKeywords` (
`idarticleKeywords` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
`articleId` INT(10) NULL,
`keywordId` INT(10) NULL,
PRIMARY KEY (`idarticleKeywords`),
KEY `idx_articlekeywords1` (`articleId`),
KEY `idx_articlekeywords2` (`keywordId`)
)
ENGINE=MyISAM
AUTO_INCREMENT=1
DEFAULT CHARSET=utf8
COLLATE=utf8_unicode_ci
COMMENT 'Linking table between Articles and Keywords';
DROP TABLE IF EXISTS `keywords`;
CREATE TABLE `keywords` (
`idkeywords` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
`keyword` VARCHAR(45) NULL,
PRIMARY KEY (`idkeywords`)
)
ENGINE=MyISAM
AUTO_INCREMENT=1
DEFAULT CHARSET=utf8
COLLATE=utf8_unicode_ci
COMMENT 'List of Keywords';
然后用一些示例数据填充它们:
INSERT INTO `keywords`
(`idkeywords`,`keyword`)
VALUES
(1,'Travel'),
(2,'Hotels'),
(3,'Boats'),
(4,'Cars'),
(5,'Trucks'),
(6,'Pack Animals');
INSERT INTO `articles`
(`idarticles`,`articleTitle`,`articlePermalink`,`articleBody`,`articleAuthor`,`createdAt`,`updatedAt`)
VALUES
(1,'Article 1','http://www.123.com/1','Some text goes here for article',1,'2017/03/28 04:10:00','2017/03/28 04:10:00'),
(2,'Article 2','http://www.123.com/2','Some more text goes here for article',3,'2017/03/28 04:10:00','2017/03/28 04:10:00'),
(3,'Article 3','http://www.123.com/3','Some other text goes here for article',2,'2017/03/28 04:10:00','2017/03/28 04:10:00'),
(4,'Article 4','http://www.123.com/4','Some even more text goes here for article',1,'2017/03/28 04:10:00','2017/03/28 04:10:00');
INSERT INTO `articleKeywords`
(`idarticleKeywords`,`articleId`,`keywordId`)
VALUES
(1,1,2),
(2,1,3),
(3,2,1),
(4,2,4),
(5,3,2),
(6,3,5),
(7,4,2),
(8,4,3),
(9,2,5);
然后我测试了插入数据之间的关系:
SELECT
a1.`idarticles` as `baseArticleId`,
a2.`idarticles` as `relatedArticleId`,
a2.`articleTitle` as `articleTitle`,
a2.`articlePermalink` as `articlePermalink`
FROM `articles` a1
JOIN `articleKeywords` ak1
ON a1.`idarticles` = ak1.`articleId`
JOIN `articleKeywords` ak2
ON ak1.`keywordId` = ak2.`keywordId`
AND ak1.`articleId` <> ak2.`articleId`
JOIN `articles` a2
ON a2.`idarticles` = ak2.`articleId`
AND a2.`idarticles` <> a1.`idarticles`
GROUP BY a1.`idarticles`,a2.`idarticles`,a2.`articleTitle`,a2.`articlePermalink`;
输出:
baseArticleId relatedArticleId articleTitle articlePermalink
1 3 Article 3 http://www.123.com/3
1 4 Article 4 http://www.123.com/4
2 3 Article 3 http://www.123.com/3
3 1 Article 1 http://www.123.com/1
3 2 Article 2 http://www.123.com/2
3 4 Article 4 http://www.123.com/4
4 1 Article 1 http://www.123.com/1
4 3 Article 3 http://www.123.com/3
最后,根据上面的示例查询创建了视图:
DROP VIEW IF EXISTS `view_articleRelated`;
CREATE VIEW `view_articleRelated` AS
SELECT
a1.`idarticles` as `baseArticleId`,
a2.`idarticles` as `relatedArticleId`,
a2.`articleTitle` as `articleTitle`,
a2.`articlePermalink` as `articlePermalink`
FROM `articles` a1
JOIN `articleKeywords` ak1
ON a1.`idarticles` = ak1.`articleId`
JOIN `articleKeywords` ak2
ON ak1.`keywordId` = ak2.`keywordId`
AND ak1.`articleId` <> ak2.`articleId`
JOIN `articles` a2
ON a2.`idarticles` = ak2.`articleId`
AND a2.`idarticles` <> a1.`idarticles`
GROUP BY a1.`idarticles`,a2.`idarticles`,a2.`articleTitle`,a2.`articlePermalink`;
这里正在使用:
SELECT *
FROM `view_articleRelated`
WHERE `baseArticleId` = 1;
返回第3和第4条。
SELECT *
FROM `view_articleRelated`
WHERE `baseArticleId` = 2;
返回第3条。
SELECT *
FROM `view_articleRelated`
WHERE `baseArticleId` = 3;
返回第1,第2和第4条。
SELECT *
FROM `view_articleRelated`
WHERE `baseArticleId` = 4;
返回第1和第3条。
答案 1 :(得分:0)
@Brian Emilius,试试这个:
SELECT
a.idarticles as `article_id`,
a2.articleTitle,
a2.articlePermalink
FROM articles a
JOIN articleKeywords ak
ON a.idarticles = ak.articleId
JOIN articleKeywords ak2
ON ak.keyword = ak2.keyword
AND ak.articleId <> a.idarticles
JOIN articles a2
ON a2.idarticles = ak2.articleId
AND a2.articleId <> a.idarticles
WHERE a.idarticles = 123
GROUP BY a2.idarticles;
FROM查找参考文章。第一个连接获取该文章的关键字列表。第二个连接查找其他文章的匹配关键字记录。最后一个联接使用相同的关键字查找文章(不包括参考文章)。
如果可行,则使用除WHERE子句之外的所有内容创建视图。
CREATE VIEW `view_articleRelated` AS
SELECT
a.idarticles as `article_id`,
a2.articleTitle,
a2.articlePermalink
FROM articles a
JOIN articleKeywords ak
ON a.idarticles = ak.articleId
JOIN articleKeywords ak2
ON ak.keyword = ak2.keyword
AND ak.articleId <> a.idarticles
JOIN articles a2
ON a2.idarticles = ak2.articleId
AND a2.articleId <> a.idarticles
GROUP BY a2.idarticles;
然后使用视图:
SELECT *
FROM `view_articleRelated`
WHERE `article_id` = 123;
答案 2 :(得分:0)
我们正在寻找与此特定文章共享关键字的其他文章::articleId
。
select other.articleTitle, other.articlePermalink
from articles this
join articles other on other.articleId <> this.articleId
where exists
(
select keywordId
from articleKeywords
where articleId in (this.idarticles, other.idarticles)
group by keywordId
having sum(articleId = this.idarticles) > 0 -- keyword occurs in :articleId
and sum(articleId = other.idarticles) > 0 -- keyword occurs in the other article
)
where this.idarticles = :articleId;
相应地创建视图。我们不是将视图本身限制在articleId
,而是选择articleId
,然后可以在查询中应用where子句:
create view view_articleRelated as
select this.idarticles as articleId, other.articleTitle, other.articlePermalink
from articles this
join articles other on other.articleId <> this.articleId
where exists
(
select keywordId
from articleKeywords
where articleId in (this.idarticles, other.idarticles)
group by keywordId
having sum(articleId = this.idarticles) > 0 -- keyword occurs in :articleId
and sum(articleId = other.idarticles) > 0 -- keyword occurs in the other article
);
查询:
select articleTitle, articlePermalink
from view_articleRelated
where articleId = :articleId;