PHP Sum from Access using Array - php

I have a question involving PHP arrays and adding up the values.
I have an access database with information in this scheme
----------------------
| time | code |
|------|-------------|
| 600 | broke down |
| 500 | broke down |
| 300 | waiting |
| 200 | waiting |
| 400 | remove coil |
Anyways, you get the idea. I have multiple code values, but can have multiple time values for one code. What I am trying to accomplish with PHP is to add up all time values and only display one code value.
The result I want would be:
1100 | Brokedown (600 & 500 added together)
500 | Waiting (300 & 200 added together)
400 | Remove Coil
Just for example. I think I should be using a multidimensional array, but I just cannot seem to wrap my head around what to do exactly with it. A point in the right direction would be greatly appreciated.

Why not SQL?
SELECT Code, Sum([Time])
FROM Table
GROUP BY Code
Time is a reserved word, so I guess it is an imaginary name. If it is real, you must enclose it in square brackets, or better, change it.

You can actually use SQL for this to return what you're looking for.
SELECT SUM(time), code FROM table_name GROUP BY code

Related

Is it possible to reference a MySQL table dynamically?

I can't find anything about dynamically referencing a MySQL table entry in my particular case. Most everything I've read leans towards it not being possible, but I'm hoping someone can prove me wrong.
Essentially, I've got multiple MySQL tables that I'm trying to pull data from on an Android app. I want to access 2 at a time. The 1st Table's name always stays the same, history. The 2nd Table's name, however, may be different at times. It's value is determined within the app and referenced with :job in my php script (I'll use moon for my example). The 2nd table itself is generated dynamically through the app, so I guess I'm trying to set up a reference within a php script I have saved to a server so that I can access the 2nd Table.
Sorry for the confusing description, I hope these tables will help explain what I'm trying to get at.
Table #1: history (always stays the same)
| site | code | hours|
|---------|---------|------|
| moon | first | 1 |
| moon | second | 2 |
| moon | third | 3 |
| earth | fourth | 4 |
Table #2: moon (this one I want to dynamically reference)
| code | hours|
|---------|------|
| first | 10 |
| second | 11 |
| third | 12 |
And my current code:
...
/*** Table #1 ***/
SELECT code,
SUM(hours) AS total, '' AS target
FROM history
WHERE site = :job /* :job ends up being moon in this example */
GROUP BY code
UNION ALL
/*** Table #2 ***/
SELECT code,
'' AS total, SUM(hours) AS target
FROM :job /* <--- I'm trying to do something along these lines and use 'moon', or 'earth', or whatever... */
GROUP BY code
...
And later I get :job from the app: (moon)
$query_params = array(
':job' => $_POST['jobname'],
);
Result I'm Looking For: (works perfect if I directly use Table #2's name (ie moon) in my php file)
| code | hours|target|
|---------|------|------|
| first | 1 | 10 |
| second | 2 | 11 |
| third | 3 | 12 |
The code absolutely works as expected when I replace the :job in the 2nd table with the actual name of the table. I'm wondering if there is some way to still do it dynamically though?
Thanks for any and all advice!
I've done some pretty extensive searching and haven't come up with anything that works for me.
Is it possible to reference a mysql table entry value from a second table entry dynamically?
https://dev.mysql.com/doc/refman/5.7/en/derived-tables.html
MySQL table.* AS reference
Retrieve parent-child hierarchy from a self-referencing mysql table

Match full string with partial value in MySQL column (postcodes)

I think the solution to this problem should be easy, but I can't find a good way around it.
I'm working with UK postcodes. My reference db looks like this:
+----+----------+----------+
| ID | postcode | leadtime |
+----+----------+----------+
| 1 | AB10 | 1 |
| 2 | AB11 | 2 |
| 3 | B7 | 3 |
| 4 | SE16WD | 1 |
+----+----------+----------+
The value in this table only represents the first half of a full UK postcode, but that's all we need to check against.
Now, the user has a form where they can type their FULL postcode to check what the lead time will be (the full postcode is then use as part of the delivery address).
Uk postcodes can have different length and you can type them with or without spaces between the first and the second half. Right now I have some PHP code that would basically take whatever was typed by the user and try to run it through all the different layout possibility, but it doesn't always work.
I'd like to find a way to do so in MySQL. I've started playing around with
SELECT leadtime FROM myTable WHERE postcode LIKE '$postcode%'
But this only works for the first few digits. As soon as the user types the entire postcode, this query won't find anything in the table.
I cannot for the life of me, find a way to match the two values!!
I'm sure I'm missing something really basic here!
Thanks a lot for your time and help with this.
EDITED the MySQL table to better reflect the variety in reference postcodes to check against.
SELECT * FROM user;
+---------+--------+
| user_id | user |
+---------+--------+
| 3 | George |
| 1 | John |
| 2 | Paul |
| 4 | Ringo |
+---------+--------+
SELECT * FROM user WHERE 'Ringo Starr' LIKE CONCAT(user,'%');
+---------+-------+
| user_id | user |
+---------+-------+
| 4 | Ringo |
+---------+-------+
I see no other way around than stripping the postcode from whitespaces and comparing your DB 'postcode' field with a 4 characters substring of that postcode.
You can always:
make a "broader" selection by using substr($postcode, 0,2);
then loop through the results and trim off the alphabetic characters from the beginning of each result using regex;
then parse the numeric string to number using intval();
and finally make a number-range comparison to narrow down the result.
The above technique may be a bit more complex, but you will have more control over the final results.
If you need a code example of how to achieve this, kindly comment and I will update the answer.
try like this
replace space by wildcard
select USERNAME FROM LOGIN_USERS WHERE USERNAME LIKE CONCAT('%',REPLACE('user_inPut',' ','%'),'%');

Group coordinates by proximity to each other

I'm building a REST API so the answer can't include google maps or javascript stuff.
In our app, we have a table containing posts that looks like that :
ID | latitude | longitude | other_sutff
1 | 50.4371243 | 5.9681102 | ...
2 | 50.3305477 | 6.9420498 | ...
3 | -33.4510148 | 149.5519662 | ...
We have a view with a map that shows all the posts around the world.
Hopefully, we will have a lot of posts and it will be ridiculous to show thousands and thousands of markers in the map. So we want to group them by proximity so we can have something like 2-3 markers by continent.
To be clear, we need this :
Image from https://github.com/googlemaps/js-marker-clusterer
I've done some research and found that k-means seems to be part of the solution.
As I am really really bad at Math, I tried a couple of php libraries like this one : https://github.com/bdelespierre/php-kmeans that seems to do a decent job.
However, there is a drawback : I have to parse all the table each time the map is loaded. Performance-wise, it's awful.
So I would like to know if someone already got through this problematic or if there is a better solution.
I kept searching and I've found an alternative to KMeans : GEOHASH
Wikipedia will explain better than me what it is : Wiki geohash
But to summarize, The world map is divided in a grid of 32 cells and to each one is given an alpha-numeric character.
Each cell is also divided into 32 cells and so on for 12 levels.
So if I do a GROUP BY on the first letter of hash I will get my clusters for the lowest zoom level, if I want more precision, I just need to group by the first N letters of my hash.
So, what I've done is only added one field to my table and generate the hash corresponding to my coordinates:
ID | latitude | longitude | geohash | other_sutff
1 | 50.4371243 | 5.9681102 | csyqm73ymkh2 | ...
2 | 50.3305477 | 6.9420498 | p24k1mmh98eu | ...
3 | -33.4510148 | 149.5519662 | 8x2s9674nd57 | ...
Now, if I want to get my clusters, I just have to do a simple query :
SELECT count(*) as nb_markers FROM mtable GROUP BY SUBSTRING(geohash,1,2);
In the substring, 2 is level of precision and must be between 1 and 12
PS : Lib I used to generate my hash

Multi-cURL 5000 URLs

I need to check for broken images with db entries. So now I am selecting all the items from table and using CURL to check it is broken or not. I have almost 5000 items in DB and CURL is taking lot of time. For one result, it is showing the total time as 0.07 seconds. My table structure is the following :
+----+----------------------------------------+
| id | image_url |
+----+----------------------------------------+
| 1 | http://s3.xxx.com/images/imagename.gif |
| 2 | http://s3.xxx.com/images/imagename.gif |
| 3 | http://s3.xxx.com/images/imagename.gif |
| 4 | http://s3.xxx.com/images/imagename.gif |
+----+----------------------------------------+
So is there any other idea to check for broken images?. I think I cannot use LIMITS here as I need to check for all items and then print the result. I have user file_get_contents() but it is also taking lot of time.
What you can do here is the following:
Use multi_curl to cURL the images in parallell.
Specify header only (as you're not interested in the image data) and if the status code is anything but 200 OK (or 302/Found), then the image does not exist.
Chunk the 5000 items first, don't run them all with multi_curl. About 50-100 items at a time is fine.

Why does this query return different values?

I'm trying to pull information from my database, but the query I'm using is only pulling all of the values after the first one. I have no LIMIT set, but I did try setting a LIMIT 0,30 with no change. In phpMyAdmin, the query returns what I expect. In my PHP file, it returns what I've explained.
The query is :
SELECT * FROM `mainSite_others` WHERE forGame='$gameName'
gameName is previously provided, and I suspect no errors because it does return at least two values. The forGame value in the database is all the same, a constant "+Stellar+Dawn".
The PHP code is:
while ($gameOther = $database->fetchArray($gameOtherQry)) {
echo $gameOther['otherName'];
}
Don't worry about the $database->fetchArray part, that is just my DB class, which works fine as far as I know.
The table I am extracting from looks like this (this is with all the values contained):
id | forGame | otherType | otherName | otherDesc
9 | +Stellar+Dawn | Character | Car | Car
10 | +Stellar+Dawn | Item | Brugson Burson | a guy
11 | +Stellar+Dawn | Item | Space Pie | A pie from space
I am using mySQLi.
Any ideas? Thank you.
You're probably doing a fetch call BEFORE you reach the while loop, which "loses" the first row of the results.

Categories