Programmatic cost for each purchase - php

I'm currently trying to identify which purchase is costing our company more than 40. Each purchase is an array of data I get through an API, and the cost is pulled from a mysql database. I have been trying with a while and a for each loop but after multiple attempt I think using one loop will be the best for performance and accuracy.
$result is the MYSQL data, and $json_array contains the API data. I would like to join the 2 data sets within a loop so I can identify the purchase_id for any purchase that costing us more than 40.
Any help much appreciated!
I have already tried 2 different loops but it won't work. It needs to be in one loop instead of 2.
//Getting the MySQL Results
$result=mysqli_query($conn,$sql);
//Creating empty array
$overspend = array();
//Starting the loop
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
//If the cost if more than 40 continue
if($row["cost"] > 40){
array_push($overspend, $row['purchase_id'] );
if (in_array($json_array, $overspend)){
$count = array_count_values($json_array);
${'_'.$row['purchase_id'].'_l'} = $count[$row['purchase_id']];
${'_'.$row['purchase_id']} = $row['cost'];
if((${'_'.$row['purchase_id']}/${'_'.$row['purchase_id'].'_l'}) > 40){
echo ${'_'.$row['purchase_id']};
}
}
}
}
}
I am not getting any error messages, I am just not getting the result expected. The expected result should be the keyword id.

Related

Query 2 tables and combine data in a single array

I am trying to combine the results from 2 queries into a single array but am having problems getting the correct code.
I have a table called PrimaryEvents that I query to add to an array. This query works ok:
$rows = query("SELECT * FROM PrimaryEvents WHERE unit = ? ORDER BY event", $unit);
I add the data to an array using the following:
foreach ($rows as $row)
{
// $event = lookup($row["event"]); (removed as spotted by sergio not required)
$event["event"] = $row["event"];
$event["validity"] = $row["validity"];
$event["eventsrequired"] = $row["eventsrequired"];
$event["unit"] = $row["unit"];
$event["role"] = $row["role"];
//now we have the data lets try and do something to it
if ($event["role"] == "0")
{
//then the user is active so change value to a YES
$event["role"] = "ALL";
}
//add our stock to the portfolio array
$portfolio[] = $event;
}
So far everything works well. I would like to query a separate table and add certain results to the array portfolio[];
$rowsCompleted = query("SELECT * FROM portfolio WHERE id = ? ORDER BY name", $_SESSION["id"]);
My original plan was to use the following additional code to add the data of interest to the portfolio[] but it doesn't work:
//now add individual stats to the array
foreach($rowsCompleted as $row)
{
if ($portfolio["event"] == $row["name"]
{
//then add our number and date to the array
$portfolio["datecompleted"] = $row["datecompleted"];
$portfolio["number"] = $row["number"];
}
//else do nothing
}
My final aim was to pull the datacompleted value and number value from the portfolio table and then add it to the array ONLY if the event name matches the name in portfolio array.
Hopefully I have described my problem and required behaviour well enough.
Thanks for nay help that can be offered, I am new to php/sql so learning as I go.
Andy
EDIT:
Also tried the following loop to try and loop through the array:
//now add individual stats to the array
foreach($rowsCompleted as $row)
{
foreach ($portfolio["event"] as $item)
{
if ($portfolio["event"] == $row["name"]
{
//then add our number and date to the array
$portfolio["datecompleted"] = $row["datecompleted"];
$portfolio["number"] = $row["number"];
}
}
//else do nothing
}
EDIT2: To try and make my question more clear: The Primary-events table lists all the events a specific user has to complete. The portfolio table tracks which events have been completed by the user (by means of date-completed and number).
I want to run a query that lists all the events from Primary-events, then into those results add the date-completed and number from the users portfolio. If the answer is blank from the portfolio then the user has not yet completed the event but I would still like to list it from the Primary-events table data.
I tried 2 queries to start with as it seemed to follow what I was trying to achieve.
EDIT3:
New code with help from Barmar
foreach ($rows as $row) {
$event = lookup($row["event"]);
$event["event"] = $row["event"];
$event["validity"] = $row["validity"];
// $event["datecompleted"] = $row["datecompleted"];
// $event["number"] = $row["number"];
$event["eventsrequired"] = $row["eventsrequired"];
$event["unit"] = $row["unit"];
$event["role"] = $row["role"];
//now we have the data lets try and do something to it
if ($event["role"] == "0") {
//then the user is active so change value to a YES
$event["role"] = "ALL";
}
//add our stock to the portfolio array
$portfolio[] = $event;
//now add individual stats to the array
foreach ($rowsCompleted as $row) {
foreach ($portfolio as &$item) {
if ($item["event"] == $row["name"]) {
//then add our number and date to the array
$item["datecompleted"] = $row["datecompleted"];
$item["number"] = $row["number"];
}
}
}
}
The page still isn't being displayed by chrome so guessing i've missed something.
EDIT4: Page displayed, I am now getting undefined index errors when the table is rendered on the html page.
Specifically the undefined index errors are for date-completed and number. I am taking it to mean that these values are not being added to the portfolio array? Do try and help I have added an Else statement (as below) to ensure that even if the event isn't available the index is:
//now add individual stats to the array
foreach($rowsCompleted as $row)
{
foreach ($portfolio as &$item)
{
if ($item["event"] == $row["name"])
{
//then add our number and date to the array
$item["datecompleted"] = $row["datecompleted"];
$item["number"] = $row["number"];
}
else
{
$item["datecompleted"] = "Never";
$item["number"] = "0";
}
}
}
EDIT 5: Near Success. Sorry to reopen this but I have just noticed behaviour I wasn't expecting: The nested loop only sets the date-completed and number for the first value to matches from the portfolio table. The follow on values are not set. It would seem like the nested loop isn't stepping through all of the portfolio values, and just exiting once the first "event" == "name".
EDIT 6: Sample data and clarification on desired functions:
portfolio sample data
|id|name |number|datacompleted
|21|event1 |3 |2014-07-07
|15|event1 |5 |2014-07-05
|21|event2 |5 |2014-05-08
|15|event1 |1 |2013-05-05
id is the id of the user that completed the event
number is the number of events completed
PrimaryEvents sample data
|id|event |validity|eventsrequired
|1 |event1 |7 |10
|1 |event2 |25 |1
|1 |event3 |12 |50
id is the id of the user that created the entry (used for historic purpose only)
The desired functionality is:
The query should create a an array to allow a html table to be created of everything within the Primary-events table. This table lists the events the user must complete.
The second query or current nested loop should gather the data from the portfolio table for the current user id, then match the event name to the name in the Primary-events array and update (if present) the number and date-completed value. (I.E populate the data for the events that the user has completed).
The current code merges the data from portfolio only for the first match, but then the nested loop seems to exit.
Hopefully this is a more clear description of what I am trying to achieve.
EDIT: I have changed the functionality to use the Left join statement below but am still having problems:
The table only contains some of the events from primary-events table and not all of them. The events being pulled over are only those that the user has completed, the ones the user has not yet completed are not being shown.
EDIT: This query seems to work:
$allEvents = query("SELECT * FROM PrimaryEvents LEFT JOIN portfolio ON (PrimaryEvents.event = portfolio.name) WHERE PrimaryEvents.event = ? AND (portfolio.id = ? Or portfolio.id is null) ORDER BY PrimaryEvents.event", $currentEvent, $_SESSION["id"]);
You need to notice that portfolio is not associative array but multidimensional array, so you cannot access it using $portfolio["event"]. You should use $portfolio[0]["event"], $portfolio[1]["event"] and so on.
It's hard to show you exact solution because I don't know how those arrays/database queries should be merged.
EDIT
It seems your query should look like this:
query("SELECT * FROM PrimaryEvents e LEFT JOIN portfolio p ON e.event = p.name WHERE e.unit = ? AND p.id = ? ORDER BY e.event", $unit,$_SESSION["id"]);
EDIT2
I haven't proposed nested loop (as it's now in modified question) because of performance loss.
You're getting closer with your second query, but still confused about what's in each array.
foreach($rowsCompleted as $row)
{
foreach ($portfolio as &$item) // Need to use reference so we can update it
{
if ($item["event"] == $row["name"])
{
//then add our number and date to the array
$item["datecompleted"] = $row["datecompleted"];
$item["number"] = $row["number"];
break;
}
}
}
To avoid the nested loop, it would be better for $portfolio to be an associative array. Change the code for your initial query to use:
//add our stock to the portfolio array
$portfolio[$event["name"]] = $event;
Then the second loop becomes:
foreach($rowsCompleted as $row)
{
$name = $row["name"];
if (isset($portfolio[$name]) {
$portfolio[$name]["datecompleted"] = $row["datecompleted"];
$portfolio[$name]["number"] = $row["number"];
}
}

how to identify unsaved value from database using php mysql

I have to identify unsaved value from mysql table using php and mysql, for example i using table named as numtab and i have already stored some numbers 1, 3, 4, 7, 23, 12, 45 in numb column.
now i have generated one new number randomly(for example 23) and i have to check this number with already stored numbers,
if 23 is exist in the table mean i have to generate another one new number and have to check once again with stored values, this process have to continue till finding unsaved number.
if generated value is not exist in table mean can stop the process and can store this number in table.
here below the format i am currently using
$numb=23;
$qryb="select * from numtab where numb='$numb'";
$results=mysql_query($qryb)or die("ERROR!!");
if(mysql_num_rows($results) == 1)
{
$numb=rand(1,100);
mysql_query("insert query");
}
the problem is above the code is validation once only, its not verifying second time. i think if using for or while loop mean can solve this problem, but i dont know how to do looping, so help me to solve this problem.
You can use in clause like this :
$qryb="select * from numtab where numb in('$numb')";
$results=mysql_query($qryb)or die("ERROR!!");
$count = mysql_num_rows($results);
if ($count > 0) {
echo "number exist in db";
} else {
echo "number does not exist in db";
}
You could make a while() loop to check if the numbers exist in your database. You could also retrieve all numbers from the database, store them in an array and check if the generated number exists within that array.
The first option would be something like this:
do {
$numb=rand(1,100);
$qryb="select * from numtab where numb='$numb'";
$results = mysql_query($qryb) or die("ERROR!!");
} while(mysql_num_rows($results) >= 1)
mysql_query("insert query");
The second option would be something like this:
$query = mysql_query("SELECT DISTINCT(numb) as numb FROM numtab");
// set array
$array = array();
// look through query
while($row = mysql_fetch_assoc($query)){
// add each row returned into an array
$array[] = $row['numb'];
}
do
{
$numb = rand(1,100);
}
while(!in_array ( $numb , $array) ;
mysql_query("insert query");

What is my last row_number in mysql query?

I have a query like this:
$sql = "SELECT * FROM doctors WHERE city ='$city' LIMIT 10 ";
$result = $db->query($sql);
And I show the result like this :
while($row = $result->fetch_object()){
echo $row->city;
}
The Problem :
Mysql , will search through my database to find 10 rows which their city field is similar to $city.
so far it is OK;
But I want to know what is the exact row_number of the last result , which mysql selected and I echoed it ?
( I mean , consider with that query , Mysql selected 10 rows in my database
where row number are:
FIRST = 1
Second = 5
Third = 6
Forth = 7
Fifth = 40
Sixth = 41
Seventh = 42
Eitghth = 100
Ninth = 110
AND **last one = 111**
OK?
I want to know where is place of this "last one"????
)
MySQL databases do not have "row numbers". Rows in the database do not have an inherent order and thereby no "row number". If you select 10 rows from the database, then the last row's "number" is 10. If each row has a field with a primary id, then use that field as its "absolute row number".
You could let the loop run and track values. When the loop ends, you will have the last value. Like so:
while($row = $result->fetch_object()){
echo $row->city;
$last_city = $row->city;
}
/* use $last_city; */
To get the row number in the Original Table of the last resultant (here, tenth) row, you could save the data from the tenth row and then, do the following:
1. Read whole table
2. Loop through the records, checking them against the saved data
3. Break loop as soon as data found.
Like So:
while($row = $result->fetch_object()){
echo $row->city;
$last_row = $row;
}
Now, rerun the query without filters:
$sql = "SELECT * FROM doctors";
$result = $db->query($sql);
$rowNumber = 0;
while($row = $result->fetch_object()) {
if($row == $last_row) break;
$rowNumber++;
}
/* use $rowNumber */
Hope this helps.
What you can do is $last = $row->id; (or whatever field you want) inside your while loop - it will keep getting reassigned with the end result being that it contains the value of the last row.
You could do something like this:
$rowIndex = 0;
$rowCount = mysqli_num_rows($result);
You'd be starting a counter at zero and detecting the total number of records retrieved.
Then, as you step through the records, you could increment your counter.
while ( $row = $result->fetch_object() ) {
$rowIndex++;
[other code]
}
Inside the While Loop, you could check to see whether the rowIndex is equal to the rowCount, as in...
if ($rowIndex == $rowCount) {
[your code]
}
I know this is a year+ late, but I completely why Andy was asking his question. I frequently need to know this information. For instance, let's say you're using PHP to echo results in a nice HTML format. Obviously, you wouldn't need to know the record result index in the case of simply starting and ending a div, because you could start the div before the loop, and close it at the end. However, knowing where you are in the result set might affect some styling decisions (e.g., adding particular classes to the first and/or last rows).
I had one case in which I used a GROUP BY query and inserted each set of records into its own tabbed card. A user could click the tabs to display each set. I wanted to know when I was building the last tab, so that I could designate it as being selected (i.e., the one with the focus). The tab was already built by the time the loop ended, so I needed to know while inside of the loop (which was more efficient than using JavaScript to change the tab's properties after the fact).

Twitter API User Lookup 1000 users

I'm trying to fetch 1000+ Twitter users from my database using this API call. However, Twitter lookup only allows 100 users per call, so how can I do it with 10 calls?
If I have 2232 users in my DB and I want to do a lookup on all users and get their details how to do it? Something which will count all the users being searched, break it into array of 100 elements, make the call for 100, and add the response back to database and then move onto the next 100.
I am using the tmhOAuth library for Twitter.
EDITED:
I was able to accomplish it using this code , but my next question is how can i bind those values back to my account ? because the screen_name is a entry and not the KEY of the array, so how can i do it ?
$accounts = $this->accounts->getAll();
$accounts_chunk = array_chunk($accounts,100);
foreach($accounts_chunk as $accounts){
$screen_names = "";
$last_key = end(array_keys($accounts));
foreach($accounts as $k => $account){
$screen_names .= $account->screen_name;
if($last_key == $k){
$screen_names .= "";
} else {
$screen_names .= ",";
}
}
$code = $this->twitter->request('GET', $this->twitter->url("1/users/lookup"),array('screen_name' => $screen_names));
echo "<pre>";print_r(json_decode($this->twitter->response));echo "</pre>";
}
But how to update values in DB using this .. i did a check but the sequence of the responses always changes so cannot use the current keys ..
You could loop through the max number of users and every hundredth time loop through hundred users and do your Twitter-magic there.
$iNumUsers = 2232; // or a mysql_num_rows-like result;
for($i = 0; $i < $iNumUsers; $i++) {
if($i % 100 == 0) {
for($j = $i; $j < 100; $j++) {
// your twitter-code here
}
}
}
Hi here are some simple steps to do this task
1: Get screen names from your db with limit of 100
2: impload with comma (join them with comma)
3: Send these 100 to users/lookup call and get data
4: (important) IF YOU RECEIVE AN ERROR OF "Rate limit exceeded" THEN USE PROXY
proxy will give you another chance to make next call of 100 users
5: decode json and send data to db
(important) if you use user's id instead of screen name then it will be easy to update db
Still have problem shout a comment here
The Twitter API says
You are strongly encouraged to use a POST for larger requests.
So try posting your 2,000 IDs to them.
With regards to the second part of your question
the sequence of the responses always changes so cannot use the current keys ..
Start with your array of user IDd - $ids
Get the response from Twitter as $tl
// Place the users into an array
$sortedUsers = array();
foreach ($tl as $user) {
$user_id = $user->id;
// $tl is *unsorted* - but $ids is *sorted*. So we place the users from $tl into a new array based on how they're sorted in $ids
$key = array_search($user_id, $ids);
$sortedUsers[$key] = $user;
}
// Sort the array by key so the most recent is at the top
ksort($sortedUsers);

php query does not retrieve any data?

well, i wanna pull out some data from a mysql view, but the wuery dos not seem to retrieve anything ( even though the view has data in it).
here is the code i've been "playing" with ( i'm using adodb for php)
$get_teachers=$db->Execute("select * from lecturer ");
//$array=array();
//fill array with teacher for each lesson
for($j=0;$j<$get_teachers->fetchrow();++$j){
/*$row2 = $get_lessons->fetchrow();
$row3=$row2[0];
$teach=array(array());
//array_push($teach, $row3);
$teach[$j]=mysql_fetch_array( $get_teachers, TYPE );
//echo $row3;*/
$row = $get_teachers->fetchrow();
//$name=$row[0]+" "+$row[0]+"/n";
//array_push($teach, $row1);
echo $row[0]; echo " ";echo $row[1]." ";
//$db->debug = true;
}
if i try something like "select name,surname from users", the query partially works . By partially i mean , while there are 2 users in the database, the loop only prints the last user.
the original query i wanted to execute was this
$get_teachers=$db->Execute("select surname,name from users,assigned_to,lessons
where users.UID=assigned_to.UID and lessons.LID=assigned_to.LID and
lessons.term='".$_GET['term']."'");
but because it didnt seem to do anything i tried with a view ( when you execute this in the phpmyadmin it works fine(by replacing the GET part with a number from 1 to 7 )
the tables in case you wonder are: users,assigned_to and lessons. ( assigned_to is a table connecting each user to a lesson he teaches by containing UID=userid and LID=lessonid ). What i wanted to do here is get the name+surname of the users who teach a lesson. Imagine a list tha displays each lesson+who teaches it based on the term that lesson is available.
Looking at http://adodb.sourceforge.net/ I can see an example on the first page on how to use the library:
$rs = $DB->Execute("select * from table where key=123");
while ($array = $rs->FetchRow()) {
print_r($array);
}
So, you should use:
while ($row = $get_teachers->fetchrow()) {
instead of:
for ($j = 0; $j < $get_teachers->fetchrow(); ++$j) {
The idea with FetchRow() is that it returns the next row in the sequence. It does not return the number of the last row, so you shouldn't use it as a condition in a for loop. You should call it every time you need the next row in the sequence, and, when there are no more rows, it will return false.
Also, take a look at the documentation for FetchRow().
for($j=0;$j<$get_teachers->fetchrow();++$j){
... a few lines later ...
$row = $get_teachers->fetchrow();
See how you call fetchrow() twice before actually printing anything? You remove two rows from the result set for every 1 you actually use.
while ($row = $get_teachers->fetchrow()) {
instead and don't call fetchrow() again within the loop.
Because you're fetching twice first in the loop
for($j=0;$j<$get_teachers->fetchrow();++$j){
... some code ...
// And here you fetch again
$row = $get_teachers->fetchrow();
You should use it like this
while ($row = $get_teachers->fetchrow()) {

Categories