2017-02-08 17 views
4

СценарийPHP/MySQL: как динамически изменять мой (большой и всегда меняющегося) базы данных

У меня есть база данных MySQL с 10000 строк. Настройка базы данных:

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

enter image description here

Это мой код:

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


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

ответ

1

Вам необходимо сохранить переменную «идентичный счет» ($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; 
} 
+0

Обновлено, чтобы исправить сохраняемость на цикле итерации –

+0

Спасибо @StevenMoseley! Извините за поздний ответ, но этот ответ действительно приятный! Это работает только частично. Прямо сейчас, первый элемент с «счетом 0» имеет значение «count = 2», а 2-й, 3-й и 4-й позиции с «счетом 0» имеет значение «count = 3». Есть ли шанс, что вы можете мне помочь? Прямо сейчас это становится слишком сложным для меня ... Спасибо заранее! Ты спасатель – JuliusSecret

0

Вы можете изменить $ SQL-запрос:

$sql = "SELECT *,count(*) FROM database group by Score order by Score"; 

В этом случае, вы не получать счет с числом и не более выбрать необходимую в то время петля.

Даже вы можете выбрать ПЕРСЕНТИЛЬ в запросе 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 

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