I'm trying to count the number of passed quizzes, as per the following results table:
So, we have 3 quizzes, and if the proportion of correct answers is >= 0.5, then it is passed. If the answer is correct, the result column shows 1, otherwise it shows 0.
For example, quiz 1 has 5 questions, of which 3 are correct. Quiz 2 has 3 questions, of which 1 is correct. Quiz 3 has 2 questions, both are correct.
So, this user has passed 2 quizzes out of 3.
My expected result is: "2 quizzes out of 3 are passed." using MYSQL with PHP with something like:
$number_of_quizzes = 'SELECT COUNT(DISTINCT quiz_id) FROM TABLE'
But, I'm struggling with the query to count the number of rows in the 'result' column and the sum of its values - per quiz.
Is this possible to do with MYSQL alone, or should the logic be transferred to PHP? How?
Can anyone help?
Try this :
$quiz_list = 'SELECT DISTINCT quiz_id FROM TABLE'
$count = 0
$number_of_quizzes = 'SELECT COUNT(DISTINCT quiz_id) FROM TABLE'
foreach ($quiz as &$quiz_list) {
$nb_quiz = 'SELECT COUNT(*) FROM TABLE WHERE quiz_id = ' . $quiz . '';
$nb_correct = 'SELECT COUNT(*) FROM TABLE WHERE quiz_id = ' . $quiz . ' AND result = 1';
$count += ($nb_correct / $nb_quiz > 0.5 ? 1 : 0);
}
$expected_result = $count . " quizzes out of " . $number_of_quizzes . " are passed.";
Of corse you have to change my SQL queries in string to real queries.
Related
I have a a table in my DB that has multiple columns with numbers I would like to query all the rows in 1 query with separate totals for all rows in each column in my db.
like so
$sql = '
SELECT sum(TOTAL1)
, sum(TOTAL2)
, sum(TOTAL3)
, sum(TOTAL4)
FROM TABLE WHERE ID = '.$ID.'';
it works when I do it with a single column query like this.
$sql = 'SELECT sum(TOTAL1) FROM TABLE WHERE ID = '.$ID.'';
but I can't seem to get it to work for multiples in 1 query does anyone know of a more proper way of doing this instead of in separate queries?
$sql = 'SELECT (sum(TOTAL1)+sum(TOTAL2)+sum(TOTAL3)+sum(TOTAL4)) AS FINALTOTAL FROM TABLE WHERE ID = '.$ID.'';
Use aliases.
Sidenote: Add your WHERE clause to the tested examples I've given below.
SELECT sum(TOTAL1) as total1, sum(TOTAL2) as total2
which if you want to use seperate aliases, is handy if you wish to echo them as different entities.
For example:
$query = mysqli_query($con, "SELECT SUM(col1) as total1,
SUM(col2) as total2,
SUM(col3) as total3 FROM table ");
while($row = mysqli_fetch_array($query)){
echo $row['total1']; // echo'd 125
echo "<br>";
echo $row['total2']; // echo'd 225
echo "<br>";
echo $row['total3']; // echo'd 2000
}
Sidenote: My three columns contained the following:
col1 in 2 rows 25, 100
col2 in 2 rows 25, 200
col3 in 2 rows 1000, 1000
To echo the total of all rows and for example: (and inside the while loop)
$total = $row['total1'] + $row['total2'] + $row['total3'];
echo $total;
Or in one go and as one alias and one row echo'd:
SELECT sum(TOTAL1 + TOTAL2 + TOTAL3) as total FROM table
I.e.:
$query = mysqli_query($con, "SELECT SUM(col1 + col2 + col3) as total FROM table ");
while($row = mysqli_fetch_array($query)){
echo $row['total'];
}
NOTE: DATA TYPE must be same for all fields which you want to SUM
By following query you can have SUM(field1)+SUM(field2)+ SUM(field3) .....n in 1 single field
I used this query for just 2 fields and both are integers
See this is my table definition
create table `siso_area_operativa` (
`id_area_operativa` int ,
`area_operativa` varchar (8),
`responsable` int
);
and this is query which you want
SELECT SUM(a.field1) FROM
(
SELECT
SUM(id_area_operativa) field1
FROM
siso_area_operativa
UNION ALL
SELECT SUM(responsable) field1
FROM
siso_area_operativa ) AS a
Result of this is
SUM(id_area_operativa) + SUM(responsable) in single field
ENJOY !!!!!!!!!!!!
Is it possible to select x random rows from a table, where one of the rows have to be a special row (thereby with a special field value) within one query?
Basically what I'm trying to create is a Guessing Game, where you have x amount of questions, with x amount of possible (checkbox selectable) answers!
This is how I select the answers currently... With 2 query's
$answers = 4; // This is the max amount of answers
// Just for testing the question_id is manually set
$query = "SELECT * FROM `answers` WHERE `question_id` = 0 AND `correct` != 1 ORDER BY RAND() LIMIT " . ($answers - 1) . "";
$query = "SELECT * FROM `answers` WHERE `question_id` = 0 AND `correct` = 1 LIMIT 1";
The "question_id" tells which question we are talking about, and the "correct" just tells if that field is the correct answer
So is it possible to select x random rows from a table, where one of the rows have to be "the correct one", within one query?
may be use UNION ?
$answers = 4;
$query = "SELECT * FROM `answers` WHERE `question_id` = 0 AND `correct` != 1 ORDER BY RAND() LIMIT " . ($answers - 1) . "";
$query .= " UNION ";
$query .= "SELECT * FROM `answers` WHERE `question_id` = 0 AND `correct` = 1 LIMIT 1";
With one single query, you will be able to get the desired result
http://dev.mysql.com/doc/refman/5.0/en/union.html
$query = "SELECT * FROM answers WHERE ... whatever ... AND `question_id` IN (5, 9, 12, 16, 2)
So, you first find the number of rows and then put the correct answer's ID in to the WHERE IN statement. Because you know the one you want, you can just surround it with random IDs from the table and then render them in a random fashion.
Ok, so I have some MySQL tables as follows:
Buildings
Building-ID Building-Name
===========----=============
1 Building-1
2 Building-2
3 Building-3
4 Building-4
Building-1
Mroom State
=====----======
1 Booked
2 Empty
3 Empty
4 Empty
Building-2
Mroom State
=====----======
1 Booked
2 Empty
3 Empty
4 Empty
And a query in PHP as follows (Ignore the hard coded while, I've simplified the code a bit):
$sql = "select * from Buildings";
$result = mysql_query ($sql) or die(mysql_error());
while ($row = mysql_fetch_array($result))
{
$building[] = $row['ward_name'];
}
$v1 = 0;
while ($v1 < 4)
{
$sql = "SELECT COUNT(*) FROM `$building[$v1]` WHERE state = 'Empty'";
$result = mysql_query($sql) or die(mysql_error());
$count = mysql_result($result, 00);
var_dump($count[$v1]);
$v1 = $v1 + 1;
}
To my way of thinking this should create an array of the buildings contained in the "Buildings" table, start a loop, load the building name from the array and provide a row count for the table of how many rows contain "Empty" in the state column. What it actually does is provide a count for the first table and then provides "NULL" for the rest.
I'd appreciate any help you can give me.
Cheers!
What about changing your data model?
Table buldings can be kept as is:
Buildings
Building-ID Building-Name
===========----=============
1 Building-1
2 Building-2
3 Building-3
4 Building-4
New table:
Rooms
Building-ID Mroom State
===========-=====-=====
1 1 1
1 2 0
2 1 0
State 0 = Empty, State 1 = Booked
Then use a join with group by:
select count(*) from buildings b inner join rooms r on r.bid = b.id where r.state = 0 group by b.id;
Then you will get a row for each building with the count of empty rooms. You won't need a table for each building.
This does noit make sense:
$count = mysql_result($result, 00);
var_dump($count[$v1]);
you mean to write:
$count[$v1] = mysql_result($result, 00);
var_dump($count[$v1]);
Also do not use several tables with names matching columns of other tables.
You can use one table with a primary key that spans two columns instead, for example create primary key on($buildingid,$roomid)
so that the table has columns $buildingid,$roomid, and $state.
mysql_result() returns a string, not an array.
Modify the code and check that now it works as expected.
var_dump($count);
So there is this database table:
and this array with selected options:
$options[1] = 1;
$options[2] = 5;
$options[3] = 3;
$options[4] = 2;
$options[5] = 1;
...
$options[x] = y;
Now, the aim is to fetch all item_ids, where if there is an option_id in its row from one of the options array's keys, the value must be the same as the value in the options array.
For example:
option 1 has selected value 1
option 2 has selected value 5
option 3 has selected value 4
option 4 has selected value 2
so we should select item_id 1 and other item_ids, where if option 1 -> option 1 = 1 AND if option 2 -> option 2 = 5 AND if option 3 -> option 3 = 4 AND ...
The item_ids will be used in IN() to select the items data from the items table.
The main point is that the user selects some options on a page, then the options are put into array, then I must find all items that comply with the selected options. In the table above we have the relation between the items and the options, and the option values per item which are predefined.
$where = array();
foreach($options as $key => $value) $where[] = 'option_id = ' . $key . ' AND option_value = ' . $value;
$sql = 'SELECT DISTINCT item_id
FROM table
WHERE (' . explode(') OR (', $where) . ')';
I might have completely misunderstood your question however.
I think this might do it for you. Haven't tested it at all and it'll probably blow up, but...
SELECT *
FROM items
WHERE (item_id in (
SELECT item_id
FROM optiontable
WHERE ((option_id = 1) and (option_value = 1)) or
((option_id = 2) and (option_value=5)) or
((option_id = 3) and (option_value=3)) or
((option_id = 4) and (option_value=2)) or
((option_id = 5) and (option_value=1))
GROUP BY CONCAT(option_id, ',', option_value)
HAVING COUNT(CONCAT(option_id, ',', option_value)) = 5
));
Basically, the inner query pulls out all the rows that match one of the member rows in your required options row. It does an artificial grouping/count on the paired option_id/option_value pairs and returns the item_ids of the rows where the number of opt_id/opt_val pairs add up to 5 rows.
You'd have to build such a query dynamically in the client, so that the number of 'where' clause entries matches the number in the having clause.
<?php
$options = array(
1 => 1,
2 => 5,
3 => 3,
4 => 2,
5 => 1
);
$cases = array();
foreach($options as $id => $value){
$cases[] = "WHEN $id THEN $value";
}
$query =
'SELECT item_id '.
'FROM your_table '.
'WHERE option_value = CASE option_id '.implode(' ', $cases).' '.
'GROUP BY item_id';
echo $query;
?>
Output (formatted by me):
SELECT item_id
FROM your_table
WHERE option_value = CASE option_id
WHEN 1 THEN 1
WHEN 2 THEN 5
WHEN 3 THEN 3
WHEN 4 THEN 2
WHEN 5 THEN 1
GROUP BY item_id
Test this query and let me know if it works the way you expect it to. :)
Update: Suggestion for your final query
$query =
'SELECT * FROM items '.
'WHERE id IN('.
'SELECT item_id '.
'FROM your_table '.
'WHERE option_value = CASE option_id '.implode(' ', $cases).' '.
'GROUP BY item_id)';
if i have a query like :
SELECT * FROM table WHERE id IN (3,6,1,8,9);
this array of the ids is build in php dynamically ,
and the order is important to me.
$my_array = array (3,6,1,8,9) ;
how can i sort the results by the order by which the elements appear in my array ?
its possible to do it in MYSQL query,
or i must to order it after via php ?
You can order by a value derived from a column. You can use a CASE operator to specify the order:
SELECT * FROM table
WHERE id IN (3,6,1,8,9)
ORDER BY CASE id WHEN 3 THEN 1
WHEN 6 THEN 2
WHEN 1 THEN 3
WHEN 8 THEN 4
WHEN 9 THEN 5
END
I haven't tested but this PHP solution should work:
<?php
$my_array = array (3,6,1,8,9) ;
$sql = 'SELECT * FROM table WHERE id IN (3,6,1,8,9)';
$sql .= "\nORDER BY CASE id\n";
foreach($my_array as $k => $v){
$sql .= 'WHEN ' . $v . ' THEN ' . $k . "\n";
}
$sql .= 'END ';
echo $sql;
?>
This generates the following SQL code:
SELECT * FROM table WHERE id IN (3,6,1,8,9)
ORDER BY CASE id
WHEN 3 THEN 0
WHEN 6 THEN 1
WHEN 1 THEN 2
WHEN 8 THEN 3
WHEN 9 THEN 4
END
If you must do it this way you'll have to manipulate the data in PHP. MySQL can only order by natural orderings ascending or descending.
Got to question though - why do you need the data returned in this very specific order? There may be an easier solution to your problem by re-jigging something further up in the code.
SELECT * FROM table WHERE id IN (3,6,1,8,9) ORDER BY FIELD(id,3,6,1,8,9);
You can load the results into an array with IDs as indexes:
while ($row = mysql_fetch_array($l)) $items[$row['id']] = $row;
and then simply iterate it in your order
foreach ($my_array as $id) { $current_row = $items[$id]; ... }