Creating a trigger to count the total price of a bill - sql

I have these tables in my restaurant database:
PRODUCT, ORDER, AND BILL(you may find them in the attached picture)
i want to create a trigger to count the total amount of the bill(i can count it by selecting sum(O_Quantity * P_Price)).
Actually i want it after inserting the ORDER's data(the order table should be empty, but i entered some data to help in understanding the question)
I do appreciate your help
thx

Related

How do you make a SQL table reflect vertical records in a horizontal fashion

I have two tables, one has sales records and one has deduct records. There is a primary key that links the two tables called Sales_ID but there are multiple deduct records that belong to one sales record. I am trying to get the sales information and the deduct information on one line. See below for tables and the desired result.
Sales Table:
Deducts table:
Desired results:
SELECT SALES.SALES_ID, SALES.SALE_QTY, SALES.SALE_AMT
FROM SALES
LEFT JOIN DEDUCTS
ON SALES.SALES_ID = DEDUCTS.SALE_ID
I understand that If I add a deduct code in the select statement I will get duplicates, but I don't know what to try to avoid that.
thanks in advance!

How to create a relationship where all columns have many details

I am working in a small personal project about capital expenses. There is one part I can't figure it out.
The tables i have are the following:
capex_form
capex_cashflow
When I create a capex_form I am able to request money and divide this money however I want in 13 months including this month (to show how I I will pay it in the next year). this will reflect in capex_cashflow who has 13 columns with either an amount or 0.
The problem comes here:
I need to be able to add many descriptions for each payment. For example:
in July 2019 I will spend 200 ( this is done), I need to enter a breakdown of this 200 dollars and a description. 50 dollars on one thing and 150 on another thing.
I added 3 columns per month which works, But then it will only let me add one description per month.
I was thinking I might be able to create another table for description, but how this is going to related to a specific column(month). As far as my brain gives, you relate one table with another table not column.
I also was thinking to create 13 tables for 13 months, but I think there should be something I am missing to avoid to create 13 unnecessary tables.
I appreciate any kind of help or guidance
This is pretty straightforward and a common thing.
Put an index column in the "header" table. The header table is a summary of the information, so in your case may you create a table that just takes the capex_income.
CAPEX_FORM
Capex_id
Capex_Amount
Then create a payment table, the payment table can have a month column (only 1) and a capex_Id column, along with a description or whatever else you need
CAPEX_PAYMENT
Capex_payment_id
Capex_id
Payment_Amount
Month (1-13)
Description
Now because you have the Capex_id in this table, it will be related to the CAPEX table and you will be able to query all the payments that are associated like so
select payment_amount, month, description from capex_payment p join capex_form f on p.capex_id = f.capex_id

How do you store quantities of items in an SQL database? (Postgresql)

I'm trying to think of the most straightforward way to store quantities of an item in a database. I'm creating a database to work in conjunction with a web app I'm developing to monitor and log gear lent out to people. So, I've thought a few different ways already, though I'm not sure if they will be easy to maintain into the future.
Idea 1
I have a gear table that stores the types of gear (e.g. shirt, pants, hat) along with data like sizes etc. Then for each time gear is taken out, it is logged in the gear_inventory table, storing details such as user id, gear type and boolean to signify if it was returned and return date. Then to track quantities, we'll have total_quantiy and count of gear out for a specific gear item in the gear table, this being updated manual with a second query triggered when an item is taken out or returned to plus or minus the given quantity.
Idea 2
Have the aforementioned total quantity out linked to the gear_inventory as a count of all non-returned items of that type.
Idea 3
Have an update task to change these quantities on table update or insert. Then do the same by adding or subtracting the quantity of a given query.
Idea 1 would be the easiest but not as reliable as the others. Idea 2 being the most reliable the handling of quantities is entering on the database to ensure. Then Idea 3 not as reliable since it's still relying on a scheduled task to update it.
So, how would you implement a quantity amount to ensure it doesn't get out of sync with the logged inventory records?
Edit 1
More info - The core solution I am trying to achive is having a method of storing or having a count of items taken out which can be compared to a total nunber associates with that item. As suggeated below, it will act in a similar fashsion to a bowling alley's loaning/borrowing shoes, exect users will be logged. So a record will be inserted when an item is borrrowed, and that record will be updated with return date on return. The types of items will be in its own table to store details on a general item, and that will have a one to many relationship with the logged gear table. The problem is, what is a full proof/reliable way to store/retrieve number of items out. Or am I overthinking this and a simple count query would sufice, not sure how intensive count is when performed oved and over again.
Let's think about what we're keeping track of.
Information about kinds of items.
Current inventory.
Which item?
How many?
What's been loaned out.
To whom?
Which items?
How many?
What's been returned.
By whom?
Which items?
How many?
First cut might look something like this:
create table items (
id serial,
name text,
...
);
create table inventory (
id serial,
item integer references items(id),
quantity integer check(quantity >= 0)
);
create table loans (
id serial,
user integer references users(id),
item integer references items(id),
quantity integer check(quantity >= 0),
when_loaned timestamp not null default now(),
when_returned timestamp
);
When you loan something out, insert a row into loans. When its returned, set loans.when_returned. If loans.when_returned is null, it's still out.
You could decrement the inventory when items are loaned, and increment it when they're returned. To preserve data integrity this should be done as a trigger, not as a scheduled process.
Alternatively, don't change the inventory quantities. Instead, subtract the number of loaned items from the amount in inventory. That's select sum(quantity) from loans where item = ? and when_returned is null from select quantity from inventory where item = ?. This makes loans and returns simpler, and avoids the possibility of the inventory count being corrupted, but it might cost performance problems if there's many, many outstanding loans.
What happens if you loan out 5 items and they return 3? How do you track that? One simple option is to split a single loan into two loans.
-- Copy the loan row
insert into loans
select * from loans where id = :orig_id
-- Track that 3 were returned
update loans
set quantity = 3, returned = now()
where id = :orig_id
-- Two are now outstanding
update loans
set quantity = 2
where id = :new_id
Without knowing more about what you're using this for, what the use cases are, and what the scale is, that's about all I can say. It's a good starting point.

Count Distinct Records and

I have a very large database and I need to extract information from 3 columns:
I am trying to determine how many unique customers the user is processing.
Username. This is unique name.
CustomerNumber. A customer number will appear on many lines, as they could have ordered many products and each product is a line.
Date Range. I need to be able to define a date range.
The code I am tried and searched is counting the customer numbers, but not just the distinct customer number.
I have not tried the date range as yet.
I have attached 2 images to show an example of the database and the end result. We used a pivot table to produce this result, but the data changes all the time and we dont want to create a pivot table the whole time.
Image of Sample Data in Excel:
Image of Required Final Result
SELECT `'All data$'`.Username, Count(`'All data$'`.CustomerNumber)
FROM `C:\Users\rhynto\Desktop\Darren Qwix\QWIX_PICKED.xlsx`.`'All data$'` `'All data$'`
GROUP BY `'All data$'`.Username
I will appreciate any advice on this please.

Crystal Report XI - Conditional Sum Issue

I have a table with data called InvoiceShipments. It continues a row for each product shipped on an invoice. Each product belongs to a product category, which I can query and filter by. Some of the products are finished good products with a Bill of Material, where the Bill of Materials (BOM) is a list of the parts that combine to make the finished good.
In the InvoiceShipments table, the finished good is listed with a price but no cost. It is then followed by the components (BOM) of that finished good, which in turn have a cost but no price. I have a separate table that lists all of the component items and which finished goods it goes to. Note that component goods can belong to more than one BOM.
I can currently filter the InvoiceShipments by the products that I want based on the product category (from a join to a different table). What I want to do is grab that finished good number, and get a list of all the part #s that make up that BOM, then go back to the InvoiceShipments and sum the costs for all of the rows that match those component #s and invoice#. But I haven't been using Crystal long enough to know what to do at the query level, what to do with a command table, what to do with a formula, etc.
Sample Screenshots:
Top table in the gallery is BOM table, second table is the InvoiceShipments, and the third is the desired outcome.
Any help would be appreciated.
From what I gather you want to combine the invoice number but use the finished product information. I've done something similar, solution is a little weird but it works. You only need your InvoiceShipments table
Group by invoice number
Create a formula for Order ID, SKU and ProductName
IF Price <> 0 AND Cost = 0 THEN
Orider ID '<-Change this according to the formula (SKU, ProductName)
ELSE
""
Insert-> Summary on each of the formula as Maximum and place it on the grouped invoice line.
Since the Quantity is constant you can put that field on the grouped invoice line.
Insert-> Summary on Price then on Cost using SUM and place it on the grouped invoice line.
Hide the details.
This should give you the result you need. What's happening is because your formula is only printing the finished goods information, the other items are blank. So when you use MAXIMUM, the non-blank items will print.
Hope this helps.
NEW SOLUTION
I don't have any tables or views that is setup like your data so I can't test this solution, but hopefully there is enough info that you can formulate a good solution
I noticed that you can't use the materials in the InvoiceShipments to idenfity the Finished Product in BillofMaterials. The Materials repeats itself. We'll have to identify them using the finished product.
Add in InvoiceShipments and rename it InvoiceShipments1 (when adding tables, the right side windows, right click on the table and rename.
Using select expert, isolate your finished products. (Price <> 0 and Cost = 0)
Database -> Database Expert. Add in your BillofMaterials table. Link SKU to ProductSKU. Left Outer Join
Now the materials are associated with an invoice number, We can try and link another copy of the INvoiceShipments to the BOM. This is tricky.
Database -> Database Expert. Add in your InvoiceShipments table rename to InvoiceShipments2. Link InvoiceShipments2.invoice# to InvoiceShipments1.Invoice#, and InvoiceShipments2.SKU to Material#. Use Left Outer Join
Create a formula that alternates between InvoiceShipments1 and InvoiceShipments2 on columns OrderID, SKU, and ProductName
IF ISNULL({InvoiceShipments1.OrderID}) THEN
{InvoiceShipments2.OrderID}
ELSE
{InvoiceShipments1.OrderID}
Create a formula combining InvoiceShipments2.invoice# and SKU (SKU formula version)
Group by formula in previous step (If the invoice contains 2 finished products, it will create 2 lines for one invoice.
On the GF put InvoiceShipments2.invoice#, OrderID (formula version), SKU (formula version), ProductNmae (formula version), InvoiceShipments2.quantity, Summerize(InvoiceShipments2.price), Summerize(InvoiceShipments2.cost)
Hide GH
Hope it works!