Mysql
 sql >> Baza danych >  >> RDS >> Mysql

percentyl według COUNT(DISTINCT) ze skorelowanym WHERE działa tylko z widokiem (lub bez DISTINCT)

Prawdopodobnie powiedziałbym, że zapytanie jest powolne, ponieważ wielokrotnie uzyskuje dostęp do tabeli po uruchomieniu wyzwalacza.

Nie jestem ekspertem SQL, ale próbowałem złożyć zapytanie za pomocą tabel tymczasowych. Możesz sprawdzić, czy pomaga to przyspieszyć zapytanie. Użyłem różnych, ale podobnie brzmiących nazw kolumn w poniższym przykładzie kodu.

EDYTUJ : W moim poprzednim kodzie wystąpił błąd obliczeniowy. Zaktualizowano teraz.

SELECT COUNT(id) INTO @no_of_attempts from tb2;

-- DROP TABLE IF EXISTS S1Percentiles;
-- DROP TABLE IF EXISTS S2Percentiles;
-- DROP TABLE IF EXISTS S3Percentiles;

CREATE TEMPORARY TABLE S1Percentiles (
    s1 FLOAT NOT NULL,
    percentile FLOAT NOT NULL DEFAULT 0.00
);

CREATE TEMPORARY TABLE S2Percentiles (
    s2 FLOAT NOT NULL,
    percentile FLOAT NOT NULL DEFAULT 0.00
);

CREATE TEMPORARY TABLE S3Percentiles (
    s3 FLOAT NOT NULL,
    percentile FLOAT NOT NULL DEFAULT 0.00
);



INSERT INTO S1Percentiles (s1, percentile)
    SELECT A.s1, ((COUNT(B.s1)/@no_of_attempts)*100)
    FROM (SELECT DISTINCT s1 from tb2) A
    INNER JOIN tb2 B
    ON B.s1 <= A.s1
    GROUP BY A.s1;

INSERT INTO S2Percentiles (s2, percentile)
    SELECT A.s2, ((COUNT(B.s2)/@no_of_attempts)*100)
    FROM (SELECT DISTINCT s2 from tb2) A
    INNER JOIN tb2 B
    ON B.s2 <= A.s2
    GROUP BY A.s2;

INSERT INTO S3Percentiles (s3, percentile)
    SELECT A.s3, ((COUNT(B.s3)/@no_of_attempts)*100)
    FROM (SELECT DISTINCT s3 from tb2) A
    INNER JOIN tb2 B
    ON B.s3 <= A.s3
    GROUP BY A.s3;

-- select * from S1Percentiles;
-- select * from S2Percentiles;
-- select * from S3Percentiles;

UPDATE tb1 A
    INNER JOIN
    (
    SELECT B.tb1_id AS id, (C.percentile + D.percentile + E.percentile) AS sum FROM tb2 B
        INNER JOIN S1Percentiles C
        ON B.s1 = C.s1
        INNER JOIN S2Percentiles D
        ON B.s2 = D.s2
        INNER JOIN S3Percentiles E
        ON B.s3 = E.s3
    ) F
    ON A.id = F.id

    SET A.sum = F.sum;

-- SELECT * FROM tb1;

DROP TABLE S1Percentiles;
DROP TABLE S2Percentiles;
DROP TABLE S3Percentiles;

To, co robi, to rejestrowanie percentyla dla każdej grupy wyników, a następnie po prostu aktualizowanie tb1 kolumna z wymaganymi danymi zamiast ponownego obliczania percentyla dla każdego wiersza ucznia.

Powinieneś również zindeksować kolumny s1 , s2 i s3 do optymalizacji zapytań w tych kolumnach.

Uwaga:Zaktualizuj nazwy kolumn zgodnie ze schematem bazy danych. Zwróć też uwagę, że każde obliczenie percentyla zostało pomnożone przez 100 ponieważ uważam, że percentyl jest zwykle obliczany w ten sposób.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySql - Aktualizuj tabelę za pomocą instrukcji Select z tej samej tabeli

  2. GROUP i COUNT() wieki w CakePHP

  3. Wywołaj funkcje zagnieżdżone/wewnętrzne mysql w querydsl

  4. Java:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:nie można utworzyć połączenia z serwerem bazy danych

  5. Zachowaj podziały wierszy z TextArea podczas pisania w MySQL