Sumowanie wartości z bazy danych

0

Mam mały problem i nie wiem co mam zmienić.

Ogólnie tworzę sobie stronę do rozwiązywania testów. Gdy użytkownik wyśle test, chce żeby automatycznie zliczyło mu punkty z odpowiedniego testu.
W tabeli w BD test_answers mam id, user_id, question_id, test_id, select_answer, points.

W pierwszej kolejności pobieram testy, które zostały wypełnione przez danego użytkownika:

$select_solved_test = $pdo -> query("SELECT * FROM test_solved WHERE user_id = '". $user['id'] ."'") -> fetchAll();

Następnie pobieram te testy i pobieram ID odpowiedniego testu, po czym pobieram wybrane odpowiedzi w danym teście przez użytkownika.

foreach( $select_solved_test as $solved_test )
{			
    $test_id = $solved_test['test_id']; // pobrane ID testu
    $select_answers = $pdo -> query("SELECT * FROM test_answers WHERE test_id = '". $test_id ."' AND user_id = '". $user['id'] ."' ORDER BY id") -> fetchAll();

    foreach($select_answers as $answers)
    {
        $points += $answers['points'];
    }
}

W ostatnim etapie chce zliczyć punkty konkretnego testu. I tutaj się pojawia pytanie, co musze poprawić, żeby poprawnie zliczać punkty danego testu? Bo aktualnie zlicza poprawnie punkty z pierwszego testu, ale z drugiego i kolejnego dodaje punkty z poprzednich testów.

4

Po pierwsze policzyć to na bazie jakimś

SELECT sum(points), test_id FROM test_answers WHERE  user_id = 1  group by test_id

I co oznacza, że liczy dobrze tylko dla pierwszego?

0

O! Nie pomyślałem o sum(points). Chyba problem rozwiązany, dziękuję bardzo!

0

Mam jeszcze pytanie...

Mam problem z sumowaniem maksymalnej możliwej ilości punktów za wypełniony test.

Napiszę, jak wyglądają tabele:

Tabela: questions ma kolumny: id, type, test_A, test_B, test_C, test_D, correct_answer, test_points
Tabela: test ma kolumny: name, questions

Kolumna questions w tabeli test zawiera ID z tabeli questions w formie tablicy: ["1","2","3"].

I teraz jak napisać zapytanie, żeby na podstawie wybranego testu i przypisanych pytań do tego testu, pobrać i zsumować z tabeli questions punkty?

0

Czyli rozumiem, że masz JSON z ID jako id pytań (prawdopodobne) w kolumnie questions. W zależności od bazy musisz go wyprasować, zmienić na tabelę i powiązać z tabelą questions.
To dla MYSQLa - https://dev.mysql.com/doc/refman/8.0/en/json-table-functions.html - nie testowałem nie używałem, ale wygląda, że to,.
To dla postgreSQL - json_array_elements(json) - https://www.postgresql.org/docs/9.3/functions-json.html

0

tak używam JSON, zacząłem robić tak:

$select_test = $pdo -> query("SELECT * FROM test WHERE id = '". $solved_test['test_id'] ."'") -> fetch();
$select_questions = $select_test['questions']; // pobieramy pytania z testów
$select_questions = json_decode($select_questions);

rozumiem, że teraz powinienem dać

foreach($select_questions as $q)
{
...
}

I tutaj problem, że nie umiem dokładnego zapytania napisać do BD (mysql), żeby sprawdzić czy w danym teście jest odpowiednie id pytania z bazy pytań i zsumować ilości punktów tych pytań.

0

Najpierw wklej schemat tabeli jaki masz i co zrobisz jesli w tescie sa np dwie odpowiedzi poprawne ? bo na razie ograniczyles sie tylko do jednej co jest totalnie bez sensu

0

Tabela questions:

  • id
  • test_question (pytanie)
  • test_answer_A – test_answer_D
  • test_correct_answer (poprawna odpowiedź)
  • test_points (ilość punktów za dane pytanie)

Tabela test:

  • id
  • name (nazwa testu)
  • questions (id pytań z tabeli questions jako tablica, np. ["1","3","5",6"])
  • status

Tabela test_answers:

  • id
  • user_id
  • question_id
  • test_id
  • select_answer (wybrana odpowiedź użytkownika)
  • points (zdobyte pkt za pytanie)
  • date_response (data wysłania)

Tabela test_solved:

  • id
  • user_id
  • test_id
  • date_solved

i co zrobisz jesli w tescie sa np dwie odpowiedzi poprawne ? bo na razie ograniczyles sie tylko do jednej co jest totalnie bez sensut...

Nie przewiduje więcej niż 1 odpowiedzi poprawnej w pytaniu. Testy jednokrotnego wyboru.

3
verluro96 napisał(a):
$select_solved_test = $pdo -> query() -> fetchAll();

Nie rób tak bo się prosisz o SQL Injection. Poczytaj o tym tutaj https://www.w3schools.com/sql/sql_injection.asp

Użyj zamiast tego takiego kodu:

$query = $this->pdo->prepare("SELECT * FROM test_solved WHERE user_id = :id");
$query->bindParam(':id', $user['id'], PDO::PARAM_INT);

1 użytkowników online, w tym zalogowanych: 0, gości: 1