Attualmente sto scrivendo una webapp che corrisponde agli utenti in base alla domanda con risposta. Ho realizzato il mio algoritmo di corrispondenza in una sola query e l'ho ottimizzato fino ad ora che sono necessari 8,2 ms per calcolare la percentuale di corrispondenza tra 2 utenti. Ma la mia webapp deve prendere un elenco di utenti e scorrere l'elenco che esegue questa query. Per 5000 utenti ci sono voluti 50 secondi sul mio computer locale. È possibile inserire tutto in una query che restituisce una colonna con user_id e una colonna con la corrispondenza calcolata? O una stored procedure è un'opzione?SQL: tabella utente di ritorno con colonna calcolata per percentuale di corrispondenza?
Attualmente sto lavorando con MySQL ma sono disposto a cambiare database se necessario.
Per chiunque sia interessato nello schema e dati, ho creato uno SQLFiddle: http://sqlfiddle.com/#!2/84233/1
e la mia query corrispondente:
SELECT COALESCE(SQRT((100.0*as1.actual_score/ps1.possible_score) * (100.0*as2.actual_score/ps2.possible_score)) - (100/ps1.commonquestions), 0) AS perc
FROM (SELECT SUM(imp.value) AS actual_score
FROM user_questions AS uq1
INNER JOIN importances imp ON imp.id = uq1.importance
INNER JOIN user_questions uq2 ON uq2.question_id = uq1.question_id AND uq2.user_id = 101
AND (uq1.accans1 = uq2.answer_id
OR uq1.accans2 = uq2.answer_id
OR uq1.accans3 = uq2.answer_id
OR uq1.accans4 = uq2.answer_id)
WHERE uq1.user_id = 1) AS as1,
(SELECT SUM(value) AS possible_score, COUNT(*) AS commonquestions
FROM user_questions AS uq1
INNER JOIN importances ON importances.id = uq1.importance
INNER JOIN user_questions uq2 ON uq1.question_id = uq2.question_id AND uq2.user_id = 101
WHERE uq1.user_id = 1) AS ps1,
(SELECT SUM(imp.value) AS actual_score
FROM user_questions AS uq1
INNER JOIN importances imp ON imp.id = uq1.importance
INNER JOIN user_questions uq2 ON uq2.question_id = uq1.question_id AND uq2.user_id = 1
AND (uq1.accans1 = uq2.answer_id
OR uq1.accans2 = uq2.answer_id
OR uq1.accans3 = uq2.answer_id
OR uq1.accans4 = uq2.answer_id)
WHERE uq1.user_id = 101) AS as2,
(SELECT SUM(value) AS possible_score
FROM user_questions AS uq1
INNER JOIN importances ON importances.id = uq1.importance
INNER JOIN user_questions uq2 ON uq1.question_id = uq2.question_id AND uq2.user_id = 1
WHERE uq1.user_id = 101) AS ps2
È possibile combinare la sottoespressione "domande comuni" delle due "gambe" della query. È inoltre possibile generalizzare le sottoquery per utente = 1 e utente = 101 in una query CTE generalizzata (se i DBMS li suppongono, ma prima: per favore mostraci le definizioni di tabella e forse alcuni dati. – wildplasser
Sì, dati con la rispettiva uscita desiderata –
Ho creato un SQLFiddle con cui giocare :) Quando abbino gli utenti 1 e 5 il risultato dovrebbe essere '43 .678 'http://sqlfiddle.com/#!2/84233/1 – Mexxer