sql >> Database teknologi >  >> RDS >> Mysql

percentil med COUNT(DISTINCT) med korreleret WHERE fungerer kun med en visning (eller uden DISTINCT)

Jeg vil nok sige, at forespørgslen er langsom, fordi den gentagne gange får adgang til tabellen, når udløseren udløses.

Jeg er ingen SQL-ekspert, men jeg har forsøgt at sammensætte en forespørgsel ved hjælp af midlertidige tabeller. Du kan se, om det hjælper med at fremskynde forespørgslen. Jeg har brugt forskellige, men lignende klingende kolonnenavne i mit kodeeksempel nedenfor.

REDIGERING: Der var en regnefejl i min tidligere kode. Opdateret nu.

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;

Hvad dette gør er, at det registrerer percentilen for hver scoregruppe og så til sidst bare opdaterer tb1 kolonne med de nødvendige data i stedet for at genberegne percentilen for hver elevrække.

Du bør også indeksere kolonnerne s1 , s2 og s3 for at optimere forespørgslerne på disse kolonner.

Bemærk:Opdater venligst kolonnenavnene i henhold til dit db-skema. Bemærk også, at hver percentilberegning er blevet ganget med 100 da jeg mener, at percentilen normalt beregnes på den måde.




  1. Hvordan viser man MySQL-databaser på et PHP-script?

  2. Repræsentation af datoer, tidspunkter og intervaller i PostgreSQL

  3. Opretter forbindelse til MySQL via SSL ved hjælp af PHP

  4. PostgreSQL Opret indeks