I have one question about my database.
table inventory
_______________________________________
id_item | item_name | quantity |price |
--------+------------+----------+------+
1 | brake | 20 |60 |
--------+------------+----------+------+
2 | oil filter | 20 |80 |
--------+------------+----------+------+
table invoice
______________________________
id_invoice | items | quantity |
-----------+-------+----------+
1 | 1,2 | 4, 1 |
-----------+-------+----------+
So I'm going to display back items in a table as an invoice ( view purpose )
but I'm stucked at how to explode/ display it using SQL.
I mean I want to display it like this:
table html
_________________________________________
No | item | quantity | total price |
---+------------+----------+-------------+
1 | brake | 4 | 240 |
---+------------+----------+-------------+
2 | oil filter | 1 | 80 |
---+------------+----------+-------------+
I just need a simple code to make this function. I only left this function to complete my system.
Thank you!
Follow the following steps : (dont have the patience to write the code for you right now, I am a PHP beginner too)..
Get the list of Invoice items by a select query on invoice table with the invoice number criteria.
Since your items and comma-separated in the database, get the quantity(list) field into a string variable.
Apply the explode function on the quantity(list) variable and get the output into an array.
Loop through the array and build the html rows. If you want a quick and generic function to do this, and if you know how PHP functions work, you can use readymade code html_show_array from here to accomplish this step.
Related
I don't know if this question should be here or not but i don't see any other place fit to ask my problem.
See, i am developing an online food portal which obviously sells food , snacks ,cakes and desserts.The real deal comes up when i have to sell a cake which can exist in various weights such as 0.1|0.5|0.9|...4.5 and every one of them costs different.Furthermore, every one of them are present in different quantities in warehouse.
My solution to achieve this was to provide a different row for every variant
ID | product_code | product name | Quantity | price | weight | company_id
1 | 12345 | beer cake | 34 |345 |0.5 |343434defee
2 | 12345 | beer cake | 343 |600 |1.0 |343434defee
3 | 12345 | beer cake | 4 |845 |1.5 |343434defee
4 | 12346 | vodka cake | 341 |345 |0.5 |343434deereee
Here , i looked every product to be a different product,I provided the relation using product code while to differentitate every row , i choose id,product_code as the primary key.
But, using this method involves redudancy as well, every row is looked as a different product.So if i were to display them using php it would show them as different product.
Something like this,
How do i change my structure of my database in order to achieve a single product but with different variants option on the same item?
I could use a php solution , if it's there.
Regards,
BOTjr.
Split the table into two with product_code as foreign key.
Table One
ID | product_code | product name | company_id
1 | 12345 | beer cake |343434defee
2 | 12346 | vodka cake |343434deereee
Table Two
Product_code |Quantity | price | weight
12345 | 34 |345 |0.5
12345 | 343 |600 |1.0
12345 | 4 |845 |1.5
12346 | 341 |345 |0.5
Use Table One to display items, Use Table Two is product description page to select the right quantity
I'm working on simple application using PHP and MySQL. Up to this point we needed to display items from database in HTML table. Simple pagination was implemented as well. It looks something like this:
+----+---------------------+
| 1 | Item 1 |
+----+---------------------+
| 2 | Item 2 |
+----+---------------------+
| 3 | Item 3 |
+----+---------------------+
| 4 | Item 4 |
+----+---------------------+
....
+----+---------------------+
| 5 | Item 25 |
+----+---------------------+
Not a rocket science. Now we add new functionality so we can (optionally) group items - We really create a 'lot' of identical items. We decided to add new column in database called groupID - which can be number or NULL for items not contained in any group. On web page we must display it as one element which expands when you click on it.
+----+---------------------+
| 1 | Item 1 |
+----+---------------------+
| 2 | Item 2 |
+----+---------------------+
| 3 | Item 3 |
+----+---------------------+
| 4 | Group 1 (Expanded) |
+----+---------------------+
| Group 1 Item 1 |
+---------------------+
| Group 1 Item 2 |
+---------------------+
| Group 1 Item 3 |
+----+---------------------+
....
+----+---------------------+
| 25| Item 25 |
+----+---------------------+
As you can see Number of items on one page may vary so we must treat items in group as one item, so simple 'limit 25' not working anymore. I wonder if I can make some clever mysql query which will work this way. I rather want to avoid to create new table in database which consists groups and relation to item table, because most of the groups will have only 1 Item. I don't believe this functionality will be used a lot, but You know - client. Also this system works on production for some time so I'd rather avoid such changes. Any Idea how to make it work? Also please keep it simple as possible, because this example is simplified. Real query is already bit complicated.
I also want avoid parsing it via PHP code, because it's just dumb to query all few thousands of rows and then discard all but 25-50 elements.
As you said some group ids can be null, I thought we should fix that.
When null, we use the item id to for the group and we use a prefix to make sure our new group_id is unique.
This is my solution using subqueries (not pretty, but seems to work):
SELECT
i1.id,
i1.itemgroup1
FROM (
SELECT
items.id,
IF(ISNULL(items.group_id),
CONCAT('alone-', items.id),
CONCAT('group-', items.group_id)) as itemgroup1
FROM
items
) as i1
RIGHT JOIN (
SELECT
items.id,
IF(ISNULL(items.group_id),
CONCAT('alone-', items.id),
CONCAT('group-', items.group_id)) as itemgroup2
FROM
items
GROUP BY itemgroup2
LIMIT 2
) as i2 on i2.itemgroup2 = i1.itemgroup1
** UPDATE **
Removed
WHERE
items.group_id IS NOT NULL
Say if I wanted to add the functionality of logging user actions within a web application. My table schema would look similar to the following:
tbl_history:
+----+---------+--+-----------+
| id | user_id | | action_id |
+----+---------+--+-----------+
| 1 | 1 | | 1 |
| 1 | 1 | | 2 |
| 1 | 2 | | 2 |
+----+---------+--+-----------+
A user can generate many actions so I will need to paginate this history. In order to do this I will need to figure out the total amount of rows for the user then calculate how many pages of data there should be.
Which would method be the most efficient if I were to have hundreds of users generating thousands of rows of data each day?
A)
Using the MYSQL's COUNT() function to query the amount of rows of data in the tbl_history table for a particular user.
B)
Having another table which would keep a count of history for the user within the tbl_history table.
+---------+--+---------------+
| user_id | | history_count |
+---------+--+---------------+
| 1 | | 2 |
| 2 | | 1 |
+---------+--+---------------+
This will allow me to instantly get the total count of rows with a simple query in less than 1ms.
The tradeoff is that I will need to perform more queries updating the count for each user and also again on page load.
Which method is more efficient to use? Or is there any other better method? Any technical explanation would be great.
Thanks in advance.
I'm displaying a record set using Datatables pulling records from two tables.
Table A
sno | item_id | start_date | end_date | created_on |
===========================================================
10523563 | 2 | 2013-10-24 | 2013-10-27 | 2013-01-22 |
10535677 | 25 | 2013-11-18 | 2013-11-29 | 2013-01-22 |
10587723 | 11 | 2013-05-04 | 2013-05-24 | 2013-01-22 |
10598734 | 5 | 2013-06-14 | 2013-06-22 | 2013-01-22 |
Table B
id | item_name |
=====================================
2 | Timesheet testing |
25 | Vigour |
11 | Fabwash |
5 | Cruise |
Now since the number of records returned is going to turn into a big number in near future, I want the processing to be done serverside. I've successfully managed to achieve that but it came at a cost. I'm running into a problem while dealing with filters.
From the figure above, (1) is the column whose value will be in int (item_id), but using some small modifications inside the while loop of the mysql resource, I'm displaying the corresponding string using Table B.
Now if I use the filter (2), it is working fine since those values come from Table A
The Problem
When I try to filter from the field (3), if I enter a string value such as fab it says no record found. But if I enter an int such as 11 I get a single row which contains Fabwash as the item name.
So while filtering I'm required to use the direct value used in Table A and not its corresponding string value stored in Table B. I hope the point that I'm putting across is understandable because it is hard to explain it in words.
I'm clueless on how to solve the issue.
I am trying to find a good solution to accomplish the following:
I have a table which includes the name of various products, such as:
"Tide - Original Scent".
In addition, I also have the amount in there for e.g. 50 fl oz.
The problem I have right now is, that the product not only comes in containers of 50 fl oz but also in different sizes such as 75 fl oz and 100 fl oz. For each of these I have new rows in the product table:
id| productName | amount | unit
1 |"Tide - Original Scent" | 50 | "fl oz"
2 |"Tide - Original Scent" | 75 | "fl oz"
3 |"Tide - Original Scent" | 100 | "fl oz"
Now I have a web interface to perform a search on this table and whenever I search for "tide" I get all three rows - which is supposed to be like that of course. However I would like a different behavior and this is where I need your help:
Instead of returning all three rows I would like one row only. I would then need to be able to process it in php so that if the user clicks on "Tide - Original Scent" that the user is then prompted to select the size.
To add even more complexity to the task:
I also have products in the same table named:
"Tide - Mountain Spring".
In this case, it would be great to have some relations set up so I know that "Tide - Original Scent" is linked with "Tide - Mountain Spring". Within php I would then like to not only give the user the choice of selecting the size but also the (in this case) scent.
What would your recommendation be on how I can accomplish this (not the php part)?
How would your database look like?
Do I need to create a table where I map these products? How would this look like if you would create this :)
2 possibilities:
Don't store the sizes in that table - along with the other specific information. Move that to another table. Denormalize your structure.
or
Query but group by the name. For the size column, do a count(amount). If it's more than one, you can then populate a drop down with choices. This is good temporary fix.
SELECT productName, count(amount) AS numOfChoices FROM YOUR_TABLE
WHERE LOWER(productName) LIKE 'tide%'
GROUP BY productName
then after the choice is made
SELECT id, amount FROM YOUR_TABLE
WHERE id = "$selectedId"
to present a choice of sizes that will pin point which one.
I would personally setup my tables like this..
Products Table:
ID| Product ID | Product Name | Description
1 | 0404888282 | Tide - Original Scent | Smells Good
Quantity Table:
ID| Product ID | Size| Price | Quantity
1 | 0404888282 | 50 | 4.99 | 23
2 | 0404888282 | 75 | 5.99 | 120
3 | 0404888282 | 100 | 7.99 | 10
This structure you have a table for each unique item, another for the sizes and quantity of each size. Keeps the structure clean and easy to understand.
"Instead of returning all three rows I would like one row only."
SELECT DISTINCT productName FROM YOUR_TABLE WHERE LOWER(productName) LIKE 'tide%'
And you'll need a functional index on LOWER(productName) for good performance. Alternatively a case-insensitive collation sequence could be used on DBMSes that support that (e.g. MS SQL Server).
"I would then need to be able to process it in php so that if the user clicks on "Tide - Original Scent" that the user is then prompted to select the size."
SELECT amount FROM YOUR_TABLE WHERE productName = whatever_user_selected
"To add even more complexity to the task: I also have products in the same table named:
"Tide - Mountain Spring"."
The query above will also return that.
What you can do is :
$Query = 'SELECT productName, amount, unit FROM products';
$Data = array();
while($Assoc = mysql_fetch_assoc($Query)){
if(!isset($Data[$Assoc['productName']])){
$Data[$Assoc['productName']] = array();
}
$Size = $Assoc['amount'].' '$Assoc['unit'];
$Data[$Assoc['productName']][] = $Size;
}
// Now what you can do is :
foreach($Data as $ProductName => $Amount){
echo $ProductName.' has :<br />';
if(count($Amount) > 0){
foreach($Amount as $Key => $Value){
echo $Value.'<br />';
}
} else {
echo 'Nothing<br />';
}
}
This however doesn't solve the problem on MySQL's side. IT will work in PHP wihtout problem. It's not beautiful but it's working.
For the first problem, you could create two tables:
products - this is where you store all the information about a product except for the specifics such as different sizes, colors, etc.
attributes - you would link to the product and for each attribute you specify a value
products
id | description
---+------------
1 | crazy shirt
2 | clown shoe
attributes
product | name | value
--------+-------+-------
1 | color | green
1 | color | blue
1 | size | medium
2 | size | large
You can optimize the attributes table further by creating a attribute_names table (and even an attribute_values table).
For your second problem, you could either:
create a related product id column inside the products table; this would limit you to only one related product per product.
create a related product table in which you store combinations between two products.
related_products
product_id | related_product_id
-----------+-------------------
1 | 2
1 | 3
That would create a relationship between product 1 and products 2 and 3.
Hope this helps.
Create a foreign key to sublabels, and order them with a counter. This will look like.
Product Table:
Product ID (key)
Brand ID
Price
Brand Table:
Brand ID (key)
Brand
Sublable Table:
ID
Product ID
Order Index
Value
Size Table:
Size ID
Value
Unit
ProductSize Table:
Size ID
Product ID
Then, you'll divide into subcategories using subsequent sublabels.
Products
10 | 6 | 1.99
11 | 6 | 2.99
12 | 6 | 3.99
13 | 6 | 1.99
14 | 6 | 2.99
15 | 6 | 3.99
Brand
6 | Tide
Sublabel
30 | 10 | 1 | Original Scent
30 | 11 | 1 | Original Scent
30 | 12 | 1 | Original Scent
30 | 13 | 1 | Mountain Spring
30 | 14 | 1 | Mountain Spring
30 | 15 | 1 | Mountain Spring
Size Table
1 | 50 | fl.oz.
2 | 75 | fl.oz.
3 | 100 | fl.oz.
Product Size Table
1 | 10
1 | 13
2 | 11
2 | 14
3 | 12
3 | 15