ฉันมีมุมมองเช่นนี้:
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 ในฟีเจอร์ 1) ในการประทับเวลา: 1,2,24,26,27,45 และผู้ใช้ต้องการจัดกลุ่มการปฏิเสธที่อยู่ใกล้กันมากกว่า 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 เรียงลำดับอัตโนมัติ จำกัด จำนวนเรกคอร์ดและอื่น ๆ
แต่มันเป็นเพียงวิธีแก้ปัญหาที่น่าเกลียด มีวิธีที่เหมาะสมในการทำเช่นนี้หรือไม่?