Conditional query depending on 2 checkbox - php

I am creating a query that depends on several input form values, and at some point I am working on three values. The first value queried has to be always 0, so I have this:
.. AND value_1 = 0
What I want to be able to do cleanly is the following:
If checkbox_2 is checked:
... AND (value_1 = 0 OR value_2 = 0)
If checkbox_3 is checked
... AND (value_1 = 0 OR value_3 = 0)
If checkbox_2 and checkbox_3 are checked
... AND (value_1 = 0 OR value_2 = 0 OR value_3 = 0)
I am creating the SQL query in a string, and I am wondering what would be a clean way to do this.

The cleanest way is to create an array filled with the options used in your SQL query and either implode the string together.
<?php
$options = array();
$options[] = 'value_1';
$options[] = 'value_2';
// add our condition to each column
array_walk($options, function(&$v) {
$v = sprintf('%s = 0', $v);
});
// implode into SQL
$sql = sprintf('... AND (%s)', implode(' OR ', $options));
Just make sure you hook up your check-boxes to the $options array.

Do you want to that checkbox_1 is always checked plus checkbox_2 or checkbox_3? That would look like this
... AND value_1 = 0 AND (value_2 = 0 OR value_3 = 0)

Related

How do I place in order 3,4 and 5 values based on amount (high-low) php

I started writing this code to determine which value within 3 date of births was the highest. As I got to as far as you can see I realised this was a silly way of doing it. There will at times be 4 values or even 5 values so writing every combination like this is sloppy.
$new_date_year1 etc are pre defined from a html form.
Can someone recommend another way of doing this.
$valuename1 = "Tom";
$valuename2 = "Jack";
$valuename3 = "Fred";
if ($amount == "3") {
if ($new_date_year1 > $new_date_year2 and $new_date_year1 > $new_date_year3 and $new_date_year2 > $new_date_year3) {
$highest_amount = $valuename1;
$second_amount = $valuename2;
$third_amount = $valuename3;
}
else if ($new_date_year1 > $new_date_year2 and $new_date_year1 > $new_date_year3 and $new_date_year3 > $new_date_year2) {
$highest_amount = $valuename1;
$second_amount = $valuename3;
$third_amount = $valuename2;
}
}
Thanks is advance for any help
just in html form replace variable names from $new_date_year1 into $new_date_year[] etc.
then in php You will have array that is sortable, so:
$new_date_year[] = '2015';
$new_date_year[] = '2018';
$new_date_year[] = '2016';
You can insert data to the array in this way as well(using array_push):
// implementing an empty array.
$new_date_year = [];
//using array_push
//you can pass multiple values to the array for explain it further i will pass '2015','2016','2018' to the array.
array_push($new_date_year,'2015','2016','2018');
After adding the values to the array you can sort the array using rsort which ,
sorts an array in reverse order (highest to lowest).
rsort($new_date_year);
$highest_amount = $new_date_year[0];
$second_amount = $new_date_year[1];
$third_amount = $new_date_year[2];

PHP: If MYSQL Result greater than 0, add to array?

I have a MYSQL table with a list of services that user's provide:
The Enum values in these columns can be 0 or 1.
0 represents a service not offered and 1 represents a service offered.
Cleaning Tour Guide Cooking Parties
0 1 0 1
I am then running the following query In MYSQL to fetch my rows in the table:
<?php $myBio = $conn->query("SELECT * FROM user_data, user_services WHERE user_data.user_id = user_services.user_id AND user_id = $p_id");
if ($myBio->num_rows > 0) {
$row = $myBio->fetch_assoc();?>
I want to generate a list of the services the user provides (where the service has a value greater than 0) - and separate the list with commas like so:
Tour Guide, Parties
I am trying to do this by using an array:
$os = array(if($row['cleaning'] > 0) { echo 'cleaning';}, if($row['tour'] >0) { echo 'Tour Guide'; });
I am trying to use PHP if statements to decipher if a service is 0 or 1 before adding it to my list.
I do not believe it is possible to combine php if statements within an array.
Please can someone show me how I can achieve my desired result? Thanks in advance
Use array_keys() with the optional search parameter:
$services = array_keys($row, 1);
Example:
$row = [
'Cleaning' => 0,
'Tour Guide' => 1,
'Cooking' => 0,
'Parties' => 1,
];
$services = array_keys($row, 1);
var_export($services);
Result:
array (
0 => 'Tour Guide',
1 => 'Parties',
)
Demo
If your database columns have a speaking name, you can do it like this:
<?php
$arrayServices = array();
$arrayAllServices = array('Cleaning','Tour Guide','Cooking','Parties');
foreach($arrayAllServices as $service) {
if($row[$service] > 0) {
$arrayServices[] = $service;
}
}
$sServices = join(', ', $arrayServices);
echo $sServices;
If the speaking names are different from the column names, you need a second array to look up translations.
Would something like this achieve what you want?
$results=array();
if ($row['cleaning']>0) $results[]='Cleaning';
if ($row['tour']>0) $results[]='Tour Guide';
// ...
Also, please heed #tadman's comment about prepared statements!
<?php
$myResults = array();
$myBio = $conn->query("SELECT * FROM user_data, user_services WHERE user_data.user_id = ? AND user_id = ?");
$stmt->bind_param("ss",$user_services.user_id,$p_id);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows === 0) exit('No rows');
while($row = $result->fetch_assoc())
{
$tempArray = array();
$Cleaning = $row['Cleaning'];
$Tour_Guide = $row['TourGuide'];
$Cooking = $row['Cooking'];
$Parties = $row['Parties'];
if($Cleaning == 1)
array_push($tempArray,$Cleaning)
if($Cleaning == 1)
array_push($tempArray,$Cleaning)
if($Cooking == 1)
array_push($tempArray,$Cooking )
if($Parties == 1)
array_push($tempArray,$Parties )
array_push($myResults,$tempArray);
}
?>
You will then get the myResult array which will be an array of arrays, you can then loop over the sub arrays to check values and construct the strings you intend to make.

Iterating through PHP array with duplicate records and deleting one record where a value = 0

I have a MySQL query using Laravel that I convert to a PHP Array.
The rows have values similar to this:
name | override | percentage
Eclipse | 1 | 50%
Eclipse | 0 | 75%
MySQL query
select * from table
Both rows (it's many more than just 2 in reality) have the same name, but one has override set to 0 and one has it set to 1.
How can I get rid of all records in my query result (PHP array) that are duplicates (determined by the name) AND have override set to 0? I want only the records that have been overridden with a new record which I have done, but I need a way to remove the records with override = 0, given that the records are the same but have a different percentage value.
How can this be done?
Thanks.
Try following query,
SELECT * from testtable GROUP BY `name` HAVING count(`name`) = 1 OR `override` = 1;
check this sqlfiddle
If I understand your needs correctly, you need to filter out records that have duplicate name and override = 0.
If you sort your result set by name (SELECT * FROM TABLE ORDER BY name), you can use this function.
function removeDuplicatesFromArray($rows) {
$result = array();
$old_name = '';
foreach($rows as $row) {
if($row['name'] != $old_name) {
$result[] = $row;
$old_name = $row['name'];
}
elseif($row['override'] == 1) {
array_pop($result);
$result[] = $row;
}
}
return $result;
}
NOTE: Doing this in SQL will be WAYYYYYYYYY faster and use far less memory. I would only try this PHP approach if you cannot modify the SQL for some reason.
Maybe try out... hit the db twice, first time only get non-overrides, then get the overrides in second pass -- coerce your arrays to be indexed by name and array_merge them. (Uses a fair chunk of memory given the number of arrays and copies - but it's easy to understand and keeps it simple.
$initial = get_non_overridden();
$override = get_overridden();
$init_indexed = index_by_name($initial);
$over_indexed = index_by_name($override);
$desired_result = array_merge($init_indexed, $over_indexed);
Assuming your database gives you a standard rowset (array of rows, where each row is a hash of fields->values). We want something that looks like this instead:
[
'Eclipse' => [
'name' => 'Eclipse',
'override' => '0',
'percentage' => '75%'
],
'Something' => [
'name' => 'Something',
'override' => '0',
'percentage' => '20%'
],
]
So index_by_name would be:
function index_by_name($rowset) {
$result = array();
foreach ($rowset as $row) {
$result[ $row['name'] ] = $row;
}
return $result;
}
There are ways to tweak your efficiency either in memory or run time, but that's the gist of what I was thinking.
array_merge then overwrites the initial ones with the overridden ones.
NOTE: this all assumes that there is only one row where Eclipse override is 1. If you have twenty Eclipse|0 and one Eclipse|1, this will work, if you have two Eclipse|1 you'd only see one of them... and there's no way to say which one.

How can I loop through an array while averaging the values of one element and only keep the newly averaged field in PHP?

I have database that contains scores which are stored daily. I want to average each months scores for each user. So far I have this:
DB structure:
id | name | tscore | added
int| string | float(100 or less)| date(2014-01-01 16:34:22)
Code:
while($row = mysql_fetch_assoc($getChartData)){ // Data from MySQL
$added_date = explode(' ',$row['added']); // Date formate 2014-01-01 16:34:22
$chartData[] = array(
'id' => $row['name'],
'tscore' => $row['tscore'],
'added' => $added_date[0] // Here I take the month only
);
}
if($_POST['range'] == 'month'){
foreach($chartData as $key => $value){
$added = explode('-',$chartData[$key]['added']);
$count = 1;
foreach($chartData as $key2 => $value2){
$added2 = explode('-',$chartData[$key2]['added']);
if($chartData[$key]['id'] === $chartData[$key2]['id'] && $added[1] === $added2[1]){ // if user is the same and the month is the same, add the scores together, increment counter, and unset 2nd instance
$chartData[$key]['tscore'] = ((float)$chartData[$key]['tscore'] + (float)$chartData[$key2]['tscore']);
$count++;
unset($chartData[$key2]);
}
}
$chartData[$key]['tscore'] = ($chartData[$key]['tscore']/$count); // Average all the scores for the month.
}
}
The problem is this method is deleting all the elements of the $chartData array. What can I try to resolve this?
You should try to solve it with MySQL. Try something like this (replace 'your_scores_table' with your table name):
SELECT
Score.name,
AVG(Score.tscore) AS `avg`,
CONCAT(YEAR(Score.added), '-', MONTH(Score.added)) AS `year_month`
FROM
your_scores_table AS Score
GROUP BY
Score.name ASC,
YEAR(Score.added) DESC,
MONTH(Score.added) DESC
;
Your logic is wrong. You are looping through the same array twice. Which means that the following if will always evaluate to true which means that array item will always get unset
//This will always be true
if($chartData[$key]['id'] === $chartData[$key2]['id'] && $added[1] === $added2[1]){
It may be simpler for you to create another array where you keep your scores. Something like
$aScores = array();
$count = 1;
foreach($chartData as $key => $value){
//Add score to a different array
$aScores[$value['name']]['tscore'] = (($aScores[$value['name']]['tscore'] + $value['tscore']) / $count);
$count++;
}
Also I would look into the MySQL AVG function. You could use that to save you having to do it in PHP

Specifying conditions on database results to array

In my database I have a field called "modules" - info data looks like this: 1, 4, 1, 3
I want to list/output all data via PHP with the numbers 1 - all other numbers have to be ignored.
I want to check the output result via an array NOT via mySQL
Any suggestion how I can do that?
$list_modules = array();
$res_m = $db->Execute("SELECT modules FROM users u WHERE user_id = '".$user->id."'");
while ( $m = $res_m->GetNext() ) {
$list_modules = array($m['modules']);
}
print_r($list_modules); //Output below
Example (Output):
Array
(
[0] => 1, 4, 1, 3
)
You can do that in you MySQL with a WHERE clause. Depending on the column name in the database:
SELECT column_name FROM table WHERE column_name = 1;
Note: In your question it looks like you tried to list a range:
with the numbers 1 - all other numbers have to be ignored.
If you meant to put a range (e.g. 1 - 4) then your WHERE clause would be:
WHERE column_name BETWEEN 1 AND 4
You should test for that in your MySQL query:
SELECT * FROM `TABLE` WHERE `modules` = 1;
Or, alternatively, if that's not possible..
Loop with foreach and test for 1?
$array = array(1,4,1,3);
foreach ($array as $element) {
if ($element == 1) { echo 1; }
}
This should do it... there is really no other way seeing at the col is Varchar, you also need to eliminate strings like 15, 21, etc. so %1% will not work.
SELECT modules FROM users WHERE user_id = ".$user->id." AND modules LIKE % 1,%
Give it a shot and let me know if it works.
You stated in your comment that the modules field contains comma-separated values, is that right? I reckon that the modules field is VARCHAR, CHAR, or any other string. If so, you could use a query like:
SELECT * FROM `tableName` WHERE `modules` LIKE '%1,%';
There may be other solutions, probably more optimal, but this one should perform well, I think.
Meh found the solution I could use.
$list_modules = array();
$query = "SELECT modules FROM users WHERE user_id = ".$user->id."";
$res_m = $db->Execute($query);
while ( $m = $res_m->GetNext() ) {
$list_modules = array('id' => $m['modules']);
}
$modules = explode(",",$list_modules['id']);
foreach ($modules as $key => $value) {
if($value == 1){
// list data
}
}
}

Categories