Tôi có một cái nhìn như thế này:
CREATE VIEW MyView AS
SELECT Column FROM Table WHERE Value = 2;
Tôi muốn làm cho nó chung chung hơn, có nghĩa là thay đổi 2 thành một biến. Tôi đã thử điều này:
CREATE VIEW MyView AS
SELECT Column FROM Table WHERE Value = @MyVariable;
Nhưng MySQL không cho phép điều này.
Tôi đã tìm thấy một giải pháp xấu:
CREATE FUNCTION GetMyVariable() RETURNS INTEGER DETERMINISTIC NO SQL
BEGIN RETURN @MyVariable; END|
Và sau đó chế độ xem là:
CREATE VIEW MyView AS
SELECT Column FROM Table WHERE Value = GetMyVariable();
Nhưng nó trông thực sự tồi tệ và việc sử dụng cũng rất tồi tệ - tôi phải đặt @MyVariable trước mỗi lần sử dụng chế độ xem.
Có giải pháp nào mà tôi có thể sử dụng như thế này không:
SELECT Column FROM MyView(2) WHERE (...)
Tình huống cụ thể như sau: Tôi có một bảng lưu trữ thông tin về yêu cầu bị từ chối:
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;
Đa số là một số yêu cầu giống nhau được ghi lại trong cùng một giây. Tôi muốn hiển thị danh sách các từ chối, nhưng đôi khi, khi ứng dụng bị từ chối, nó sẽ thử lại một vài lần chỉ để đảm bảo. Vì vậy, thông thường, khi cùng một người dùng bị từ chối 3 lần trên cùng một tính năng trong vài giây thì đó thực sự là một lần từ chối. Nếu chúng tôi có thêm một tài nguyên, để đáp ứng yêu cầu này, hai lần từ chối tiếp theo sẽ không xảy ra. Vì vậy, chúng tôi muốn nhóm các từ chối trong báo cáo cho phép người dùng chỉ định khoảng thời gian mà các từ chối sẽ được nhóm lại. Ví dụ: nếu chúng tôi có các từ chối (đối với người dùng 1 trên tính năng 1) trong dấu thời gian: 1,2,24,26,27,45 và người dùng muốn nhóm các từ chối gần nhau hơn 4 giây, anh ta sẽ nhận được một cái gì đó như sau: 1 (x2), 24 (x3), 45 (x1). Chúng ta có thể giả định rằng khoảng cách giữa các từ chối thực sự lớn hơn nhiều so với giữa các bản sao.
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;
Sau đó, để hiển thị từ chối từ người dùng 1 và 2 trên các tính năng 3 và 4 được hợp nhất cứ sau 5 giây, tất cả những gì bạn phải làm là:
SET @DenialMergingTime := 5;
SELECT GroupTime, FeatureId, UserHostId, MultiplicitySum FROM MergedDenials WHERE UserHostId IN (1, 2) AND FeatureId IN (3, 4);
Tôi sử dụng chế độ xem vì nó dễ dàng lọc dữ liệu và sử dụng nó một cách rõ ràng trong lưới jQuery, tự động sắp xếp, giới hạn số lượng bản ghi, v.v.
Nhưng đó chỉ là một cách giải quyết xấu xí. Có một cách thích hợp để làm điều này?