сценарий
У меня есть база данных MySQL с 10.000 строк. Настройка базы данных:
ID UniqueKey Name Url Score ItemValue
1 5Zvr3 Google google.com 13 X
2 46cfG Radio radio.com -20 X
3 2fg64 Yahoo yahoo.com 5 X
.... etc etc etc
Как видите, каждый предмет имеет Гол. Счет постоянно меняется. У Google сейчас может быть 13 баллов, а завтра — 80 или -50.
Что я хочу:
Я хочу создать систему, которая создает иерархию в моей текущей базе данных на основе Гол из предметов. Прямо сейчас я думаю о процентильные ряды, Это означает, что предметы с наибольшим количеством очков будут близки к 100%, а предметы с самыми низкими оценками будут близки к 0%. Для этого я создал код, который попытается достичь того, что показано здесь: http://www.psychstat.missouristate.edu/introbook/sbk14m.htm
Это мой код:
$sql = "SELECT * FROM database order by Score";
$result = $conn->query($sql);
$count = 0;
while ($row = $result->fetch_assoc()) {
$woow = $row['Score'];
$sql = "SELECT * FROM database WHERE Score = $woow";
$resultnew = $conn->query($sql);
$somanythesame = $resultnew->num_rows;
$itemPercentile = ( ($count/$result->num_rows + 0.5*$somanythesame/$result->num_rows) * 100 );
$rowID = $row['ID'];
$sql2 = "UPDATE database SET itemValue = $itemPercentile WHERE ID = $rowID";
$conn->query($sql2);
$count++;
}
Это работает, но для одной проблемы это не так: В моей базе данных много предметов, многие с тот же счет. Чтобы проиллюстрировать мою проблему, вот очень простая 10-рядная база данных только с оценками:
множество
-10
0
0
0
10
20
20
30
40
50
Проблема с моим кодом в том, что он не дает одинаковый процентиль для элементов с тот же счет, потому что это принимает во внимание все предыдущие строки для расчета, в том числе с одинаковым счетом.
Итак, для 2-го, 3-го и 4-го пункта с Score of 0
должно быть так: (1/10 + 0.5*1/10) * 100
, Проблема в том, что для 3-го пункта это будет (2/10 + 0.5*1/10) * 100
и 4-й пункт это будет делать (3/10 + 0.5*1/10) * 100
,
Затем, для 5-го пункта со счетом 10, это должен делать (4/10 + 0.5*1/10) * 100
, Это идет хорошо; только не для предметов с одинаковым счетом.
Я не уверен, что объяснил это хорошо, мне трудно выразить свою проблему правильными словами. Если у вас есть какие-либо вопросы, дайте мне знать! Спасибо за ваше время 🙂
Вы должны поддерживать «идентичный счет» ($icount
) переменная, которая отслеживает количество предметов с одинаковым баллом и «текущим баллом» ($score
) который отслеживает текущий счет.
$icount = 0;
$score = null;
инкремент $icount
вместо $count
когда $woow == $score
(проверка идентичного значения). В противном случае добавьте его в свой $count
и увеличить, а затем сбросить $icount
значение до 0.
if ($woow == $score) {
$icount++;
} else {
$count += $icount + 1;
$icount = 0;
}
Наконец, установите ваш $score
значение до последней $woow
для тестирования в следующей итерации цикла:
$score = $woow;
Это позволит предметам с одинаковым счетом иметь одинаковый $count
значение, увеличивая при этом дополнительный $icount
времена, когда новый $score
найден.
Ваш окончательный код будет выглядеть так:
$sql = "SELECT * FROM database order by Score";
$result = $conn->query($sql);
$count = 0;
$icount = 0;
$score = null;
while ($row = $result->fetch_assoc()) {
$woow = $row['Score'];
$sql = "SELECT * FROM database WHERE Score = $woow";
$resultnew = $conn->query($sql);
$somanythesame = $resultnew->num_rows;
$itemPercentile = ( ($count/$result->num_rows + 0.5*$somanythesame/$result->num_rows) * 100 );
$rowID = $row['ID'];
$sql2 = "UPDATE database SET itemValue = $itemPercentile WHERE ID = $rowID";
$conn->query($sql2);
if ($woow == $score) {
$icount++;
} else {
$count += $icount + 1;
$icount = 0;
}
$score = $woow;
}
Вы можете изменить запрос $ sql:
$sql = "SELECT *,count(*) FROM database group by Score order by Score";
В этом случае вы выбираете счет со счетом, и больше не нужно выбирать в цикле while.
Даже вы можете выбрать Percentile в запросе MySQL:
Select t2.* , @fb as N , ((t2.fb1 + 0.5 * t2.fw)/@fb*100) as percentile from (
Select t1.* , (@fb := @fb + t1.fw) as fb1 from (
Select score,count(*) as fw From tablename group by score order by score ASC
) as t1
) as t2
Я думаю, что этот запрос возвращает большинство столбцов, которые вам могут понадобиться для проверки результатов.