PhP / MySQL: как динамически менять мою (большую и постоянно меняющуюся) базу данных

сценарий

У меня есть база данных 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, Это идет хорошо; только не для предметов с одинаковым счетом.


Я не уверен, что объяснил это хорошо, мне трудно выразить свою проблему правильными словами. Если у вас есть какие-либо вопросы, дайте мне знать! Спасибо за ваше время 🙂

4

Решение

Вы должны поддерживать «идентичный счет» ($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;
}
1

Другие решения

Вы можете изменить запрос $ 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

Я думаю, что этот запрос возвращает большинство столбцов, которые вам могут понадобиться для проверки результатов.

0

По вопросам рекламы [email protected]