sql >> Databáze >  >> RDS >> Mysql

percentil podle COUNT(DISTINCT) s korelací WHERE funguje pouze s pohledem (nebo bez DISTINCT)

Pravděpodobně bych řekl, že dotaz je pomalý, protože opakovaně přistupuje k tabulce, když se spustí trigger.

Nejsem žádný odborník na SQL, ale pokusil jsem se sestavit dotaz pomocí dočasných tabulek. Můžete zjistit, zda to pomáhá urychlit dotaz. V níže uvedené ukázce kódu jsem použil různé, ale podobně znějící názvy sloupců.

UPRAVIT: V mém dřívějším kódu došlo k chybě výpočtu. Nyní aktualizováno.

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 znamená, že zaznamenává percentil pro každou skupinu skóre a nakonec pouze aktualizuje tb1 sloupec s požadovanými daty namísto přepočítávání percentilu pro každý řádek studenta.

Měli byste také indexovat sloupce s1 , s2 a s3 pro optimalizaci dotazů na tyto sloupce.

Poznámka:Aktualizujte názvy sloupců podle schématu db. Všimněte si také, že každý výpočet percentilu byl vynásoben 100 protože věřím, že percentil se obvykle počítá tímto způsobem.




  1. Kontrola, zda položka neexistuje v jiné tabulce

  2. Jak uložit data unicode do oracle?

  3. Jak naložím s remízou při hodnocení výsledků v MySQL?

  4. zachytit výjimku DB v aplikaci JSF+EJB