I have been trying to get the subgroup total of the data below using the method in the accepted answer here: how to group result in subgroups in php, but to no avail. Somebody please help.
I want this:
+---------------+-----------------+
| Type | Price |
+---------------+-----------------+
| Music | 19.99 |
| Music | 3.99 |
| Music | 21.55 |
| Toy | 89.95 |
| Toy | 3.99 |
+---------------+-----------------+
displayed as this:
Music | 45.53
Toy | 93.94
in group and subtotal.
You should do it directly in MySQL when you perform the query (if possible):
SELECT DISTINCT Type, SUM(Price) as Total FROM table_name GROUP BY Type
You could select the sum of the prices, then group the subtotals by type. I used this SQL statement in a PHP script;
SELECT SUM(Price) AS Total, Type FROM Table GROUP BY Type
I then executed the SQL statement and echoed the results in a simple foreach loop. It appears to work fine with me.
Try this...
// Get the sum
$group = array();
foreach($rows as $r){
$group[$r->type] = $group[$r->Type] + $r->Price;
}
// Display
foreach($group as $type=>$price){
echo "Type:".$type." Price: ".$price;
}
Related
How to query for erase the view below?
+-------------------+------------+
| Order_id | Weight |
| 20 | 4 |
| 21 | 5 |
| 22 | 2 |
| 22 | 2 |
+-------------------+------------+
To be like this:
+-------------------+------------+
| Order_id | Weight |
| 20 | 4 |
| 21 | 5 |
| 22 | 2 |
| 22 | |
+-------------------+------------+
When displaying results but not entered into the database.
A simple way is:
select DISTINCT order_id, weight from xyz
UNION
select order_id, null from xyz
group by order_id, weight
having count(*) > 1
Order by weight desc;
The 1st select statement will display all the unique values and 2nd one will retrieve only the repeated values.
In your required output table, it seems like you want to display all the non-repeated rows and the 1st column value of repeated rows but not 2nd column value. The above query will allow you to do that.
OK, here is how to do it:
SELECT
Order_id,
Weight,
if(#order_id = Order_id, '', Weight) as no_dup_weight,
#order_id := Order_id as dummy
FROM Table1
ORDER BY Order_id asc;
You basically need to check to see if the previous Order_id is the same as the current, and if they are, output an empty field.
Here is an SQLFiddle demonstrating the solution.
Do you actually need 2 rows for the dupes? Can't you just use the DISTINCT clause as per http://www.mysqltutorial.org/mysql-distinct.aspx
Or is it important to know what has duplicates. In which case you should look into the GROUP BY clause
I need help to make the best query posible here. I have the following Database:
+----+--------------+-----------------+------------------------------+
| id | reference_id | reference_field | value |
+----+--------------+-----------------+------------------------------+
| 1 | 6215 | title | Best recipe |
| 2 | 6215 | introText | Intro for best recipe |
| 3 | 6215 | fullText | Full text for best recipe |
| 4 | 6216 | title | Play Football |
| 5 | 6216 | introText | Intro for play football |
| 6 | 6216 | fullText | Full text for play football |
+----+--------------+-----------------+------------------------------+
I need to make a query where I group by reference_id and I should print the value by the reference_field, example of the output info:
Best recipe
Intro for best recipe
Full text for best recipe
Play Football
Intro for play football
Full text for play football
UPDATE
To accomplish this, I will print the query on the following way with PHP:
$result = $config->mysqli->query("SELECT * FROM table_name ORBER BY reference_id");
while($row = $result->fetch_array()) {
echo ('<h1>'.$row["title"].'</h1>');
echo ('<h1>'.$row["introText"].'</h1>');
echo ('<h1>'.$row["fullText"].'</h1>');
}
With the query above, I get all the records one by one (not grouped by the reference_id), in other hand if I do the query
SELECT * FROM table_name GROUP BY reference_id
How do I get the 3 values (title, introText, fullText) to print on the loop interaction in PHP?
As you can see with a normal "order by" or "group by" does not produce the proper result to print the values on the loop. What I see here is that on the result I should print the values of 3 records by each loop interaction in PHP instead print 3 fields of each records, does it make sense?
I think this is what you need:
SELECT value from TABLE_NAME
ORDER BY reference_id
You may want this:
select *
from your_table
order by reference_id, reference_field desc;
Create connection, do query and show the results:
<?php
$dbo = //Create db connection
$statement = $dbo->prepare("SELECT * FROM table_name ORBER BY reference_id");
$statement->execute();
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
echo "<pre>";
print_r ($result);
echo "</pre>";
?>
I have a MySql product table called babyfoontest where all my products are listed like this:
idnummer | ean | typenummer | merk
1 | 1111| Baby1 | Philips
2 | 2222| Baby2 | Alecto
and I have a big price table called prijzen with all prices from different webshops like this:
idnummer | shopnaam | typenummer | price | eancode | producturl | categorie
1 | Amazon | Baby1 | 9,99 | 1111 | www.test.nl| baby
2 | Amazon | Baby2 | 19,99 | 2222 | www.test.nl| baby
3 | BCC | Baby1 | 17,99 | 1111 | www.test.nl| baby
Now on my results page, I want to show 5 products with a price comparison. In my product table, every EAN is unique. I want to match it with all the EAN numbers from the price table and show all prices from min to max. How can I do this?
In the example above if the first product is on the result page, Baby1, I want to prices to show (9,99 AND 17,99) because they match on EAN.
I have this:
SELECT *
FROM babyfoontest
INNER JOIN prijzen
ON babyfoontest.ean = prijzen.eancode
LIMIT 0, 5
So the tables match, but now I get only one price from the prijzen table, and I need all the prices from that product. I use this foreach loop:
$i = 1;
foreach ($data as $info) {
echo $i;
echo ' asd '.$info->typenummer.'<br>';
echo 'asd '.$info->producturl.'<br>';
echo 'asd '.$info->deeplink.'<br>';
echo 'asd '.$info->eancode.'<br><br>';
$i++;
}
Please help me with this!
Thanks!!
Kind regards,
Mark
Perhaps you want to concatenate the prices together. Something like this:
SELECT b.ean, group_concat(p.price order by p.price) as prices
FROM babyfoontest b INNER JOIN
prijzen p
ON b.ean = p.eancode
GROUP BY b.ean
LIMIT 0, 5
I have a SQL table being created daily that is downloaded from a suppliers website,containing product info, that is in csv. I have everything creating alright and all the tables are identical. The problem that I am needing solved is that I need to compare the tables between today and yesterday (table names are the dates in following format mm-dd-yyyy) I need to compare a few different columns for different things.
I need to know all products that are in today's data that weren't in
yesterdays (can be checked by supplier SKU)
I need to know all product that were in yesterday's data that is no
longer in today's
I need to know when the price went up from yesterday's data
I need to know when the price has gone down from yesterday's data
I need to know when a sale has started based on yesterday's data as
well as stopped
These need to show the following labels in the table that will show the changes
regular up
regular down
miscillanious change (description change or change to a fields that aren't a priority)
promo on (discount added from supplier)
promo off (discount taken off by supplier)
delete (no record of the product in new list {probably been deleted})
new item (new record of product in new list)
out of stock
I have been searching everywhere for the answer for these issues and have found stuff that kind of shows me how to do this using union and join but I don't fully understand how to use them based on this scenario.
I have tried different PHP solutions by going through each piece of data and searching for the sku in the new table and vice versa then checking for any changes if they exist in both tables but this is taking a really long time and I have over 200 000 products in these tables. I am hoping that I can do these in less queries and by letting the sql server do more work then the php script.
Thanks for all the help!
Yesterday's Table
__________________________________________________________
| id | price | sale | description | qty | sku |
---------------------------------------------------------
| 1 | 12.50 | 0.00 | description product 1 | 12 | 12345 |
| 2 | 22.99 | 20.99 | describe the problem | 1 | 54321 |
| 3 | 192.99 | 0.00 | description ftw | 5 | 53421 |
| 4 | 543.52 | 0.00 | description | 15 | 45121 |
----------------------------------------------------------
Today's Table
__________________________________________________________
| id | price | sale | description | qty | sku |
---------------------------------------------------------
| 1 | 12.50 | 0.00 | description product 1 | 12 | 12345 |
| 2 | 22.99 | 0.00 | describe the problem | 1 | 54321 |
| 3 | 192.99 | 50.00 | description ftw | 5 | 53421 |
| 4 | 523.99 | 0.00 | description | 15 | 45123 |
----------------------------------------------------------
I need the new table to look like the following
_____________________________________________________________
| id | sku | label | description | price |
-------------------------------------------------------------
| 1 | 54321 | promo off | describe the problem | 22.99 |
| 2 | 53421 | promo on | description ftw | 192.99|
| 3 | 45123 | new item | description | 523.99|
| 4 | 45121 | delete | description | 543.52|
-------------------------------------------------------------
The following is the code I have for the deleted and new items currently. I am using int for the label/status in the example below and just signifying the different numbers.
$deleted = mysql_query("SELECT * FROM `test1`") or die(mysql_error());
while($skus= mysql_fetch_array($deleted))
{
$query = mysql_num_rows(mysql_query("SELECT * FROM `test2` WHERE SKU='".$skus['sku']."'"));
if($query < 1)
{
$tata= mysql_query("INSERT INTO `gday` (Contract_Price, SKU, status) VALUES (".$skus['price'].", ".$skus['sku'].", 1)");
}
}
$deleted = mysql_query("SELECT * FROM `test2`") or die(mysql_error());
while($skus= mysql_fetch_array($deleted))
{
$query = mysql_num_rows(mysql_query("SELECT * FROM `test1` WHERE SKU='".$skus['sku']."'"));
if($query < 1)
{
$tata= mysql_query("INSERT INTO `gday` (Contract_Price, SKU, status) VALUES (".$skus['price'].", ".$skus['sku'].", 2)");
}
}
EDIT:
The Following is the true table that all the data will be going into. I originally didn't want to muddy the water with the large table but by request I have included it.
ID
Status
DiscountDate
Price
Discount
DiscountEndDate
Desc1
Desc2
Desc3
Warranty
Qty1
Qty2
PricingUnit
PriceUpdate
Vendor
Category
UPC
Weight
WeightUnit
Because of the size of your database I could propose you an SQL solution.
When you work with a lot of data, PHP can be slow for several reason.
You can try to do some functions.
You just have to store the status data in an other table. This is the documentation to write a trigger.
http://dev.mysql.com/doc/refman/5.0/en/triggers.html
Becareful if you have a lot of operation on your table I can suggest you to use PostgresSQL instead of mysql because I found it more simple to write function, trigger, ... using PL/sql
EDIT: Just have to write a simple function
I'm working on it at the moment. Think about using select case like in this answer
EDIT: Core function
DELIMITER |
CREATE PROCEDURE export()
BEGIN
(SELECT today.id, today.sku,
CASE today.price
WHEN today.price = yesterday.price THEN 'nothing'
WHEN today.price < yesterday.price THEN 'promo on'
ELSE 'promo off' END AS label
FROM today, yesterday WHERE yesterday.sku = today.sku)
UNION
(
SELECT today.id, today.sku,
'new item' AS label
FROM today LEFT JOIN yesterday ON yesterday.sku = today.sku WHERE yesterday.sku IS NULL)
UNION
(
SELECT yesterday.id, yesterday.sku,
'delete' AS label
FROM yesterday LEFT JOIN today ON today.sku = yesterday.sku WHERE today.sku IS NULL
);
END|
DELIMITER ;
To call just do:
CALL export();
Here is an example of possible core functions. Be careful in this case id could be the same. In the function you'll have to add a personal one in the first column.
If you need performance to display it faster in PHP, think about APC cache
I have two different tables that share an 'is_featured' column. I need to select all content that is checked 'is_featured' and sort the results by 'date_display' desc.
PHOTOS
item_name | date_display | is_featured
photo1 | 01-02-13 | yes
photo2 | 02-12-13 | yes
photo6 | 06-24-12 | no
photo23 | 09-24-12 | no
VIDEOS
item_name | date_display | is_featured
video5 | 01-14-13 | no
video10 | 03-09-13 | no
video30 | 03-21-13 | yes
video17 | 11-14-12 | yes
DESIRED RESULTS - All FEATURED CONTENT Sorted by Date DESC
item_name | date_display | is_featured
video30 | 03-21-13 | yes
photo2 | 02-12-13 | yes
photo1 | 01-02-13 | yes
video17 | 11-14-12 | yes
I'm able to get my desired result with this UNION query:
SELECT *
FROM (SELECT item_name, date_display
FROM photos
WHERE is_featured='yes'
UNION
SELECT item_name, date_display
FROM videos
WHERE is_featured='yes'
) x
ORDER BY date_display DESC
What I need now is to be able to add unique identifiers to the item_names of each table. For examples: photos.item_name and videos.item_name.
Is that possible with the query I have?
I ultimately need to do something like the following:
If (item_name is from Photos table) { do this }
Try something like:
...
FROM (SELECT item_name, date_display, 'photo' AS media_type
FROM photos...
and similarly for the video subquery. This will create a column media_type in your result set that is 'photo' for the photos, and 'video' for the videos.
Your result set would look like this:
item_name | date_display | media_type
video30 | 03-21-13 | video
photo2 | 02-12-13 | photo
photo1 | 01-02-13 | photo
video17 | 11-14-12 | video
Exactly how you check that value depends on how you handle your query results, but here's some Code Igniter-like pseudo-code provided for concreteness. You can adapt it to whatever your situation calls for:
foreach($query->result() as $row) {
if ($row->media_type == 'photo') {
$featured_photos[$row->item_name] = $row;
}
else {
$featured_videos[$row->item_name] = $row;
}
}
That example is a little silly because it just undoes the work of the union in your query, but the point is that once you get your results back you can use the media_type field to differentiate where the items came from.