NOTE:
I'm new to php and mysql.
Background info:
I have +/- 30,000 products and they are from 7 different supplier and they have a lot of the same products
let's say i have 1 product and three of the suppliers have the it, i need to publish the product with the lowest price and the other two product stay unpublished
that is the basic idea and this must run through the 30,000 products and check and see if there are any matches and run the publishing function
SQL setup:
There are two tables xxxx_virtuemart_product and xxxx_virtuemart_product_prices
There are three rows in xxxx_virtuemart_product ▬▬▬ product_id,product_sku,published ▬▬▬
There are two rows in xxxx_virtuemart_product_prices ▬▬▬ product_id,product_price ▬▬▬
My little bit of code:
I have this little code because i'm stuck, how can i make a check to see if there are any matches and then run a query to change the published value of the product with the lowest price?
i know there is a way to use the query to check for matches, but do not understand how to do is
$query = "SELECT `product_sku` FROM `xxxx_virtuemart_product`";
$query_run = mysql_query($query) or die (mysql_error());
while($row = mysql_fetch_assoc($query_run)){
foreach ($row as $key => $ps){
}
}
The below code is to check the price (not query optimize just a rough draft)
$z = //products price;
$x = //products price;
$c = //products price;
if ($z >= $x && $c >= $x) {
//the this products published value to 1
}else if ($x >= $z && $c >= $z) {
//the this products published value to 1
}else if ($z >= $c && $x >= $c) {
//the this products published value to 1
}
Can anyone please help me with this?
Thanks for reading
any questions are welcome.
Your problem is not about to compare arrays but more algorithm.
I will try this way.
1)SQL query to retrieve all the products : sql_products
2)construct a hashmap those key is product SKU (see : PHP Array)
To construct PHP hashmap : use arrays of arrays.
Example :
product_map[] = array();
foreach sql_product of sql_products :
- product_map[sql_product[SKU]][] = array(sql_product[supplier], sql_product[price], sql_product[information])
end of loop
Then loop again over the map of products constructed and sort each product record by price : that means you have to write a function to sort array (supplier, price, information).
Now you have a map of product : SKU => array(of array (supplier, price, information))
Related
I am sorry if my title is incorrect, was not sure what these array values are called.
I am doing an api call that returns data, i want to use that data.
Now in the data it is possible to have up to 20 'offers'.
Each has their own price.
I would like to return the lowest price
The structure of the results are
results -> 0 -> offers -> "number from 0-19" -> price
So each offer (with number 0-19) will have a price.
Is there an easy way to grab all of that data at once and just output the lowest price?
$price = $price_array['results'][0]['offers']['*can i cycle this part*']['price'];
foreach ($price_array['results'][0]['offers'] as $offer) {
echo $offer['price'];
// and do what you want
}
Or maybe:
$minPrice = min(array_column($price_array['results'][0]['offers'], 'price'));
echo $minPrice;
You can use array_column and min().
$price = min(array_column($price_array['results'][0]['offers'],'price'));
This will return the lowest price in that column of the array.
I have the following SQL statement:
$query = "SELECT item, COUNT(*) as number FROM shop GROUP BY item";
This will give me the following result:
item number
item1 23
item2 15
item3 4
I want to use this to make menu items, so normally the menu would look:
item1
item2
item3
But I want to do a check if an item has less than 10 records, that I don't want to display this item.
So in this example, the menu would be like:
item1
item2
Any idea how to achieve this?
I would like to do this in PHP because I need all the items in the query but will only want to show them which are greater then 10 and need the other items later on.
If you want to do this in PHP then you can do like this
function filterArray($value){
return ($value.number > 10);
}
$filteredArray = array_filter($yourDBArray, 'filterArray');
foreach($filteredArray as $k => $v){
//your desired array
}
In terms of speed Mysql option is good as suggested above.
Just change your query from
SELECT item, COUNT(*) as number FROM shop GROUP BY item
to
SELECT item, COUNT(*) as number FROM shop GROUP BY item HAVING number>=10
As you really need to perform this in PHP you could use array_filter() which, using a closure, will remove items which number is less than 10:
$more_than_ten = array_filter($items, function ($i) { return $i['number'] >= 10; });
Doing it with SQL would be a better solution (about performances). In case you'd need it, you could use the HAVING clause (you can't perform a WHERE number >= 10):
SELECT
item,
COUNT(*) as number
FROM shop
GROUP BY item
HAVING number >= 10
I noticed php is tagged. For the sake of options, here's how I'd go about separating the unneeded data in php if you were to get it from the database as-is:
foreach ($data as $item) {
$num = (int) $item['number']; // force of habit
if ($num >= 10) {
// display it
}
}
I'd probably separate the data at the database step, but this works if it's the route you want to take.
There is two options to filter the data so only the rows with more then 10 will appear.
At the SQL query
__
SELECT item, COUNT(*) as number FROM shop GROUP BY item HAVING number > 9
This will cause you to recieve only the requested rows from the database
Filter with PHP - every time you want to print the menu or testing it out, just can the value of 'number' in the array reutrned from the query. You can also allocate new array and insert all the values that contains 'number' that bigger then 10.
I need to create promo codes which should be short in length (~ 6 characters). The promo codes have to be unique, so I need to check their uniqueness in database as well. They need to be generated in batches of thousands, so a check in db with every coupon generation is not feasible. I have created a method which first generates the required number of coupons and then check for duplicates using where in(). Having duplicate count of greater than zero, makes it generate the count again.
public function generateCoupons($count, $length = 6)
{
$coupons = [];
while(count($coupons) < $count) {
do {
$coupon = strtoupper(str_random($length));
} while (in_array($coupon, $coupons));
$coupons[] = $coupon;
}
$existing = Offer::whereIn('coupon', $coupons)->count();
if ($existing > 0)
$coupons += $this->generateCoupons($existing, $length);
return (count($coupons) == 1) ? $coupons[0] : $coupons;
}
Need suggestions how to improve upon this? Or if I can have some other way to achieve the same.
Make sure the promo code is indexed in your DB. This will speed up the search for existing promo codes.
Otherwise, your method is good! you want to check as many codes as possible at once (which you do with the whereIn/count) and only re-generate the codes that were not unique.
Build a table new_codes with 1000 candidates. PRIMARY KEY(code).
DELETE new_codes
FROM new_codes
LEFT JOIN existing_codes ON existing_codes.code = new_codes.code
WHERE existing_codes.code IS NOT NULL;
That (if I did it right) will very quickly delete the dups. Now you will have not-quite-1000 'good' codes.
I have a matrix of inputs boxes which contain prices for dates. If there is no price in the database for a particular date the input box displays 0. I have the following code which saves into the database the prices typed into the input boxes. It does not save all the 0 values only the new prices.
Which is fine. However I have now discovered an issue. If one of the inputs dislays a value from the database, say $10 and I want to set it now to 0, the code will not do it.
It will only save if the values and above 0. I have not been able to do this final check.
The conditions for saving are
1. If the value is numeric
2. If it is 0 and already has an entry in the database then save
3. If it has no value in the database and is greater than 0
4. If it is 0 and has no value in the database then do not save
if (isset($this->data['Rate'])){
// for each rate
foreach($this->data['Rate'] as $rate_id => $room){
// for each room type
foreach($room as $room_id => $room){
$price_for_today = isset($room['Price'][$key]) ? $room['Price'][$key] : 0;
// get existing availabilities is num (get this from previous date loop)
$today = ''.$date.' 00:00:00';
$conditions = array('Availability.date' => $today,'Availability.room_id'=>$room_id);
$this->Availability->contain();
$result = $this->Availability->find('all',array('order'=>'Availability.room_id ASC', 'conditions'=>$conditions));
$avail_id = $result[0]['Availability']['id'];
// check prices
$check_prices = "SELECT * FROM prices
WHERE rate_id = '".$rate_id."' AND availability_id = '".$avail_id."'";
$prices_result = $this->Availability->query($check_prices);
// if new prices > 0.00
if($price_for_today>0 && is_numeric($price_for_today)){
// better checking needed!
if($prices_result){
$setprices = "UPDATE prices SET price = '".$price_for_today."'
WHERE rate_id = '".$rate_id."' AND availability_id = '".$avail_id."'";
$update = $this->Availability->query($setprices);
} else {
$setprices = "INSERT INTO prices (price, availability_id, rate_id)
VALUES ('".$price_for_today."', '".$avail_id."', '".$rate_id."')";
$insert = $this->Availability->query($setprices);
}
}
//$errors[] = $setprices;
} // end rooms loop
} // end Rates loop
Your problem is in
> // if new prices > 0.00
> if($price_for_today>0 &&
> is_numeric($price_for_today)){
here you specify that $prices_for_today have to be >0, so if you had a price and want to put it 0 today then you will not do anything... You should use
if(($price_for_today>0 && is_numeric($price_for_today)) || (!empty($prices_result) && $price_for_today==0 && is_numeric($price_for_today))){
if you change it it will now enter in the if and do the change.
I sugest that you do NOT use the query function unless is extremely necesary. you should create a model for price (if you haven't done that already) and then use the associations (hasMany, HasOne, HABTM) or load the model directly in the controller with $this->loadModel('Price'). Then use a find 'all' as always with conditions and fields. This recomendation is to use cake as it was intended, not indispensable. Also the save, updatefield, read can be done if you do this... leaving the checks and everything to cake.
i need help with google analytics gapi class with php. (http://code.google.com/p/gapi-google-analytics-php-interface)
I want to output how many times each item in catalog was viewed. The page for the item generates with id for example:
/item.php?id=1
/item.php?id=2
ect.
So everything goes right with my code until i want to order by the most viewed item, since i am using loop, to generate random filters:
$filter = "pagePath == /item.php?id=".$i++."";
I am not able to use sort in gapi "requestReportData".
With the code shown below everyting outputs right, but i don't know how to sort everything so it will shown results from the most viewed item till least.
The code:
$ga = new gapi(ga_email,ga_password);
$dimensions = array('pagePath');
$metrics = array('pageviews');
$termFrom = 2011-06-01;
$termUntil = 2011-06-30;
echo '<strong>ITEMS VIEW STATISTIC</strong><br />';
for ( $i='1'; $i<'20';)
{
$filter = "pagePath == /item.php?id=".$i++."";
$ga->requestReportData(table_id,$dimensions,$metrics,'-pageviews',$filter, $termFrom, $termUntil);
foreach($ga->getResults() as $result)
{ $j= $i-1; $b=$j-1;
echo $z++.') Items which ID is:'.$j++.' and NAME is: '.$ItemsNamesArray[$b]['item_name'].' was viewed: '.$result->getpageviews() . ' times<br />';
}
}
It outputs:
ITEMS VIEW STATISTIC
1) Items which ID is:1 and NAME is:
Book was viewed: 9 times
2) Items which ID is:2 and NAME is:
Box: 1 times
3) Items which ID is:3 and NAME is:
Table: 3 times
4) Items which ID is:4 and NAME is:
House: 27 times
I want it to output:
ITEMS VIEW STATISTIC
1) Items which ID is:4 and NAME is:
House was viewed: 27 times
2) Items which ID is:1 and NAME is:
Book was viewed: 9 times
3) Items which ID is:3 and NAME is:
Table was viewed: 3 times
4) Items which ID is:2 and NAME is:
Box was viewed: 1 times
You can use regular expressions for filters to get all your twenty items at once and have Google Analytics sort them:
$ga = new gapi(ga_email,ga_password);
$dimensions = array('pagePath');
$metrics = array('pageviews');
$termFrom = '2011-06-01';
$termUntil = '2011-06-30';
$filter = 'pagePath=~/item\.php\?id=[0-9]*' // Matches all item URLs
$sort = '-pageviews'; // Sorted by desc. pageview count
$maxResults = 20; // First 20 entries
$ga->requestReportData(table_id, $dimensions, $metrics, $sort, $filter, $termFrom, $termUntil, 1, $maxResults);
foreach($ga->getResults as $i => $result){
// Do your magic for each item
}
This is untested, the regular expression in the filter should match correctly, though.
I assumed you want the twenty most-viewed item URLs.