我有一个视图如下:
CREATE VIEW MyView AS
SELECT Column FROM Table WHERE Value = 2;
我希望让它更加通用,也就是将2改为一个变量。我尝试了以下代码:
CREATE VIEW MyView AS
SELECT Column FROM Table WHERE Value = @MyVariable;
但是MySQL不允许这样做。我找到了一个丑陋的解决方法:
CREATE FUNCTION GetMyVariable() RETURNS INTEGER DETERMINISTIC NO SQL
BEGIN RETURN @MyVariable; END|
然后视图是:
CREATE VIEW MyView AS
SELECT Column FROM Table WHERE Value = GetMyVariable();
但它看起来真的很糟糕,使用起来也很糟糕 - 我必须在每次使用视图之前设置@MyVariable。
是否有解决方案,我可以像这样使用:
SELECT Column FROM MyView(2) WHERE (...)
具体情况如下: 我有一个存储被拒绝请求信息的表格:
CREATE TABLE Denial
(
Id INTEGER UNSIGNED AUTO_INCREMENT,
PRIMARY KEY(Id),
DateTime DATETIME NOT NULL,
FeatureId MEDIUMINT UNSIGNED NOT NULL,
FOREIGN KEY (FeatureId)
REFERENCES Feature (Id)
ON UPDATE CASCADE ON DELETE RESTRICT,
UserHostId MEDIUMINT UNSIGNED NOT NULL,
FOREIGN KEY (UserHostId)
REFERENCES UserHost (Id)
ON UPDATE CASCADE ON DELETE RESTRICT,
Multiplicity MEDIUMINT UNSIGNED NOT NULL DEFAULT 1,
UNIQUE INDEX DenialIndex (FeatureId, DateTime, UserHostId)
) ENGINE = InnoDB;
多重性是在同一秒钟内记录的相同请求的数量。我想显示一个拒绝列表,但有时,当应用程序被拒绝时,它会尝试几次以确保。因此,通常情况下,当同一用户在几秒钟内对同一功能进行3次拒绝时,实际上只有一个拒绝。如果我们有一个更多的资源来满足这个请求,那么接下来的两个拒绝就不会发生。因此,我们希望在报告中对拒绝进行分组,允许用户指定应该将拒绝分组的时间跨度。例如,如果我们有针对时间戳为1,2,24,26,27,45(用户1在功能1上)的拒绝,并且用户希望将彼此更接近的拒绝分组而不是4秒,他应该得到像这样的结果:1(x2),24(x3),45(x1)。我们可以假设真正的拒绝之间的间隔要比复制之间的间隔大得多。我通过以下方式解决了这个问题:
CREATE FUNCTION GetDenialMergingTime()
RETURNS INTEGER UNSIGNED
DETERMINISTIC NO SQL
BEGIN
IF ISNULL(@DenialMergingTime) THEN
RETURN 0;
ELSE
RETURN @DenialMergingTime;
END IF;
END|
CREATE VIEW MergedDenialsViewHelper AS
SELECT MIN(Second.DateTime) AS GroupTime,
First.FeatureId,
First.UserHostId,
SUM(Second.Multiplicity) AS MultiplicitySum
FROM Denial AS First
JOIN Denial AS Second
ON First.FeatureId = Second.FeatureId
AND First.UserHostId = Second.UserHostId
AND First.DateTime >= Second.DateTime
AND First.DateTime - Second.DateTime < GetDenialMergingTime()
GROUP BY First.DateTime, First.FeatureId, First.UserHostId, First.Licenses;
CREATE VIEW MergedDenials AS
SELECT GroupTime,
FeatureId,
UserHostId,
MAX(MultiplicitySum) AS MultiplicitySum
FROM MergedDenialsViewHelper
GROUP BY GroupTime, FeatureId, UserHostId;
如果要显示用户1和2对功能3和4的拒绝,每5秒合并一次,您需要做的只是:
SET @DenialMergingTime := 5;
SELECT GroupTime, FeatureId, UserHostId, MultiplicitySum FROM MergedDenials WHERE UserHostId IN (1, 2) AND FeatureId IN (3, 4);
我使用视图,因为在其中过滤数据并在jQuery表格中明确使用它非常容易,可以自动排序、限制记录数量等等。
但这只是一个丑陋的解决方法。有没有更好的方法来做到这一点?