Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

persentil oleh COUNT(DISTINCT) dengan WHERE berkorelasi hanya berfungsi dengan tampilan (atau tanpa DISTINCT)

Saya mungkin akan mengatakan bahwa kueri lambat karena berulang kali mengakses tabel saat pemicu diaktifkan.

Saya bukan ahli SQL tetapi saya telah mencoba menyusun kueri menggunakan tabel sementara. Anda dapat melihat apakah itu membantu mempercepat kueri. Saya telah menggunakan nama kolom yang terdengar berbeda tetapi serupa dalam contoh kode saya di bawah ini.

EDIT : Ada kesalahan perhitungan dalam kode saya sebelumnya. Diperbarui sekarang.

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;

Apa yang dilakukan adalah merekam persentil untuk setiap grup skor dan akhirnya hanya memperbarui tb1 kolom dengan data yang diperlukan alih-alih menghitung ulang persentil untuk setiap baris siswa.

Anda juga harus mengindeks kolom s1 , s2 dan s3 untuk mengoptimalkan kueri pada kolom ini.

Catatan:Harap perbarui nama kolom sesuai dengan skema db Anda. Perhatikan juga bahwa setiap perhitungan persentil telah dikalikan dengan 100 karena saya percaya bahwa persentil biasanya dihitung seperti itu.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Batasi jumlah baris untuk bergabung, di mysql

  2. Jumlah kumulatif lebih dari satu set baris di mysql

  3. Tabel MySQL dengan jumlah baris tetap?

  4. Akses ditolak; Anda memerlukan (setidaknya satu dari) hak istimewa SUPER untuk operasi ini

  5. Backup Database MySQL secara otomatis di server windows