Ho una visione come questa:
CREATE VIEW MyView AS
SELECT Column FROM Table WHERE Value = 2;
Vorrei renderlo più generico, significa cambiare 2 in una variabile. Ho provato questo:
CREATE VIEW MyView AS
SELECT Column FROM Table WHERE Value = @MyVariable;
Ma MySQL non lo consente.
Ho trovato una brutta soluzione alternativa:
CREATE FUNCTION GetMyVariable() RETURNS INTEGER DETERMINISTIC NO SQL
BEGIN RETURN @MyVariable; END|
E poi la vista è:
CREATE VIEW MyView AS
SELECT Column FROM Table WHERE Value = GetMyVariable();
Ma sembra davvero scadente, e anche l'uso è scadente: devo impostare @MyVariable prima di ogni utilizzo della vista.
C'è una soluzione che potrei usare in questo modo:
SELECT Column FROM MyView(2) WHERE (...)
La situazione concreta è la seguente: ho una tabella che memorizza le informazioni sulla richiesta rifiutata:
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;
Una molteplicità è un numero di richieste identiche registrate nello stesso secondo. Voglio visualizzare un elenco di rifiuti, ma a volte, quando l'applicazione viene rifiutata, riprova un paio di volte solo per esserne sicuro. Quindi, di solito, quando lo stesso utente viene negato 3 volte sulla stessa funzione in un paio di secondi, in realtà è un rifiuto. Se avessimo una risorsa in più, per soddisfare questa richiesta, i prossimi due dinieghi non accadrebbero. Quindi vogliamo raggruppare i rifiuti in report consentendo all'utente di specificare il periodo di tempo in cui raggruppare i rifiuti. Ad esempio, se abbiamo rifiuti (per l'utente 1 sulla funzione 1) in timestamp: 1,2,24,26,27,45 e l'utente desidera raggruppare i rifiuti che sono più vicini tra loro di 4 secondi, dovrebbe ottenere qualcosa del genere: 1 (x2), 24 (x3), 45 (x1). Possiamo presumere che gli spazi tra le smentite reali siano molto più grandi che tra le duplicazioni.
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;
Quindi per mostrare i dinieghi dell'utente 1 e 2 sulle funzioni 3 e 4 unite ogni 5 secondi, tutto ciò che devi fare è:
SET @DenialMergingTime := 5;
SELECT GroupTime, FeatureId, UserHostId, MultiplicitySum FROM MergedDenials WHERE UserHostId IN (1, 2) AND FeatureId IN (3, 4);
Uso la vista perché in essa è facile filtrare i dati e utilizzarli esplicitamente nella griglia jQuery, ordinare automaticamente, limitare il numero di record e così via.
Ma è solo una brutta soluzione alternativa. C'è un modo corretto per farlo?