0

Need help for designing my database, I have a table named transaction with columns: tr_id, item, item_cost, item_quantity, total and my problem is:

I need to divide the item_quantity from january to december:

for example:

tr_id: 1 
item: sock 
item_cost(each): 20 
item_quantity: 12 
total: 240 
jan: 
feb: 
mar: to dec:

I need a suggestion on how to design a database with this kind of entries.

3
  • You need to clarify what you are attempting. In particular, what is a "transaction"? In classic order processing systems, a transaction would have a date. You would get monthly totals by aggregating, using GROUP BY and some function that extracts the month from the date. Aug 26, 2014 at 8:31
  • Or you could write a view which "spreads" the item_quantity over 12 months. Aug 26, 2014 at 9:01
  • (example) item quantity is 10, the months: Jan Feb mar apr may jun july aug sep oct nov dec, it'll spread like 1 0 1 1 1 0 1 1 1 1 2 0
    – PHP Noob
    Aug 29, 2014 at 1:28

3 Answers 3

0

You can create two table one for saving transactions and one for saving month lookup

Something like

CREATE TABLE TransactionSales
(
TransactionID int,
ItemID int,
ItemName nvarchar(100),
Price numeric,
Quantity int,
TotalAmount numeric,
MonthId smallInt
)

CREATE TABLE Months
(
 MonthId smallInt
 MonthName varchar(20)
)

Now in code enum can be used to get the value fo monthId depending on current month and insert it in transaction table, and the fetching data with sql query will be an ease now,let me know if you need select query for this design :)

9
  • Is that the only way? or can it be the transaction id be the foreign key? so that 1 row per transaction ?
    – PHP Noob
    Aug 27, 2014 at 1:04
  • 1
    This is what I got but the transaction ID serves as the foreign key instead of the monthId. Which is better?
    – PHP Noob
    Aug 27, 2014 at 1:09
  • @AkosiTolin yes the transactionID can serves as foreign key, but the Data table will not be normalized and for every transaction you need to make an entry in Months table too which will can be skipped and hence some space can be saved
    – vijayp
    Aug 27, 2014 at 2:14
  • yes, some of the months can be skipped and the value for them will be 0.
    – PHP Noob
    Aug 27, 2014 at 3:46
  • @AkosiTolin, Sorry but don't got you on this, I mean here only 12 row for Month table one for each month, Each there any other way around you want to fetch data from transaction table apart from what you said in your post
    – vijayp
    Aug 27, 2014 at 4:18
0

You can build a view that "unpivots" the table and divides item_quantity and total by 12 for each row. The syntax would look something like this:

CREATE VIEW transactions_pivot
AS

SELECT t.td_id, t.item, t.item_cost, x.m AS month_no, t.item_quantity/12
FROM transactions AS t
CROSS JOIN (
    SELECT 1 AS m UNION ALL
    SELECT 2 AS m UNION ALL
    SELECT 3 AS m UNION ALL
    SELECT 4 AS m UNION ALL
    SELECT 5 AS m UNION ALL
    SELECT 6 AS m UNION ALL
    SELECT 7 AS m UNION ALL
    SELECT 8 AS m UNION ALL
    SELECT 9 AS m UNION ALL
    SELECT 10 AS m UNION ALL
    SELECT 11 AS m UNION ALL
    SELECT 12 AS m) AS x

The CROSS JOIN is like a regular JOIN, but without any conditions, so it produces a cartesian product (12 rows for each row in "t"). There are prettier (and faster) ways of writing the code on different platforms, but this syntax is ANSI SQL compatible.

On a side-note: I wouldn't include "total" as a column, since that's calculated from the number of items multiplied by the item price.

1
  • No Sir, I don't need to divide it by 12 , because there can be 0 quantity for other months and higher quantity for others as well. I need a design that you will be saving those inputs of item quantity needed for each month.
    – PHP Noob
    Aug 26, 2014 at 7:46
0

If you query directly from this table, you can use PIVOT but you need add more column TransactionDate into transaction table.

CREATE TABLE TransactionSales
(
TransactionID int,
ItemID int,
ItemName nvarchar(100),
Price numeric,
Quantity int,
TotalAmount numeric,
TransactionDate date
)
INSERT INTO TransactionSales 
VALUES (1,1,'Sock',20,12,240.00,'2014-01-08'),
(2,2,'Nike Shoes',200,2,400.00,'2014-01-08'),
(3,1,'Sock',10,20,200.00,'2014-08-08'),
(4,2,'Nike Shoes',250,2,500.00,'2014-08-08'),
(5,1,'Sock',20,10,200.00,'2014-02-08')

SELECT ItemName,[1] AS 'Jan',[2] AS 'Feb',[3] AS 'Mar',[4] AS 'Apr',[5] As 'May',[6] As 'Jun',[7] AS 'Jul',[8] As 'Aug',[9] AS 'Sep',[10] As 'Oct',[11] AS 'Nov',[12] AS 'Dec'
FROM
    (SELECT ItemName,MONTH(TransactionDate) AS MonthID,SUM(Quantity) AS Quantity
     FROM TransactionSales
     GROUP BY ItemName,MONTH(TransactionDate)
     ) AS SourceTable
     PIVOT 
     (
     SUM(Quantity) FOR MonthID IN([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12]) )
     AS PivotTable;

If you need to query data from reporting tables, I suggest that you create reporting tables such ItemDaily / ItemMonthly and so on.

ItemDaily: rollup data from transaction table and group by ItemID,ItemName and TransactionDate

ItemMonthly: rollup data from ItemDaily

If you need more performance, you could create more summary tables such as ItemQuarterly, ItemMonthToDate,Item_YearToDate to serve your purpose of reporting.

6
  • Thanks for helping sir, but I need a design: for example: The quantity for 'Socks' is '2' and I should spread it, example: quantity: 1 for January and the other '1' is on October ...
    – PHP Noob
    Aug 27, 2014 at 1:10
  • I assume that this database will be served your reports such as below example: Iitem Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec Sock 1 0 0 0 0 0 0 0 0 1 0 0 Beside the table TransactionSales, there is a new table Date for storing date/time information: Date(DateID,Date,Week,Month,MontName,Year) After that, you join it with TransactionSales.
    – Dung Dinh
    Aug 27, 2014 at 6:05
  • Yes sir! That's the way I want the data to be stored.
    – PHP Noob
    Aug 29, 2014 at 1:23
  • So you will have two options here. 1- Use TransactionSales and Data table join together for getting data as you want. 2- You will have a new table ItemReport (ItemID,ItemName,Jan ,Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec) and then you will pour data from TransactionSales to it. The insert step is run hourly or nightly depend on your schedule. I prefer option 1 to 2 because of flexible queries.
    – Dung Dinh
    Aug 29, 2014 at 2:51
  • if you would prefer 1, where will I store the jan,feb,...dec?
    – PHP Noob
    Aug 29, 2014 at 2:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.