sum not calculating correct no. of units in SQL command - sql

I have the following SQL script(of which the result is displayed under the script). The issue I am having is that I need to add up the quantity on the invoice. The quantity works fine when all the products on the invoice are different. When there is a product that appears twice on the invoice, the result is incorrect. Any help appreciated.

The DISTINCT keyword acts on all columns you select.
A new product introduces a difference which makes it no longer distinct. Hence the extra row(s).
Where you had:
Order Product Total
1 Toaster $10
2 Chair $20
And another item is added to order 1:
Order Product Total
1 Toaster $99
1 Balloon $99 -- Yes that's a $89 balloon!
2 Chair $20
The new row (balloon) is distinct and isn't reduced into the previous row (toaster).
To make is distinct again, don't select the product name:
Order Total
1 $99
2 $20
Uniqueness kicks in and everyone's happy!
If you can remove the column from the select list that's "different", you should get the results you need.

Related

Only Show unique Customers per date cohort for repeat purchase rate

Scenario:
I have a table that has all of the customer purchases by Month and each month has a period. Within that table I am showing the customers that have made purchases in each Month/Period. What I am trying to figure out is how to exclude any customer that made a purchase in the previous month so that the repeat purchases are only for unique customers. The data looks like the following:
customer_email
cohortMonth
month_number
orders_for_period
abc#gmail.com
10/2019
0
2
def#gmail.com
10/2019
0
1
ghi#gmail.com
10/2019
0
1
def#gmail.com
10/2019
1
1
abc#gmail.com
10/2019
1
1
def#gmail.com
10/2019
2
1
In the Table above for Month_number=0 we have 3 total customers and within this period customer abc#gmail.com was the only repeat customer because they have 2 orders. This would show as a 33% repeat purchase rate for month_number 0. For Month_number=1 we have 2 customers that have purchased again in the period but only def#gmail.com is unique as abc#gmail.com already made the purchase. This would then bring the repeat_rate to 66% as now 2 customers have comeback and purchased out of the 3 that originally purchased.
cohortMonth
month_number
repeat_purchase_rate
10/2019
0
33%
10/2019
1
66%
10/2019
2
66%
With every unique customer that purchases in the subsequent periods we want to add that to the total to understand the repeat rate at a cumulative level.
I have tried a ton of different ways to figure this out but backing out the customers that made purchases in the previous period and only showing the unique customers is where I am struggling at. Any help is greatly appreciated!
Side Note: Whenever I format a table it looks like how I want it to look in the preview but then when I review I get the error :"Your post appears to contain code that is not properly formatted as code. Please indent all code by 4 spaces using the code toolbar button or the CTRL+K keyboard shortcut. For more editing help, click the [?] toolbar icon."
I then indent and it breaks the way the table looks. Any help on that would be great as well. Thank you

SQL-Script to Automatically build pallets

I have code that I am using to call out how many pallets an item would be able to build. The issue I am having is I cannot figure out how to then automatically build pallets based on this number.
For example, if I have an item that can build 3.50 pallets, then I would want that to go into a new table that will then call out Pallet #1 and then a unique name, Pallet #2 then a unique name, Pallet #3 then a unique name. There will then be left over of .50.
I would want to then look in the category and find a ITEM that could fit with the .50 pallet item and try to make a whole pallet. In the table below, the remaining .50 of ITEM '1111' would be paired with ITEM '3333' which is .350 to then make Pallet #4, this process would then loop and find all the other combos based on the category to make the closest full pallet.
Ideally I would like the first pallets to be made on anything greater then 1, by giveng them a unique name, then using the leftovers to combine with other leftovers(items <1) to make other potentially full pallets, with a threshold of between 1 and .85:
ITEM CUBIC_INCHES PALLETS CATEGORY RANKING
1111 100,000 3.50 HIGH_TOP 1
2222 50,000 1.75 LOW_TOP 1
3333 10,000 .350 HIGH_TOP 2
4444 5,000 .175 LOW_TOP 2
My code that I am using to make this table is:
SELECT
ITEM
,CUBIC_INCHES
,CAST(CASE WHEN CUBIC_INCHES=0 THEN 0
ELSE (CUBIC_INCHES)/28,571.42 END AS DEC(38,4)) AS PALLETS
,CATEGORY
,RANK() OVER (PARTITION BY CATEGORY ORDER BY CUBIC_INCHES) AS RANKING
FROM TABLE_1

Challenging Excel VBA/Macro for inventory management

I work for an eCommerce company and we use Microsoft Excel for our inventory database. We currently just keep adding items to this database as we purchase them, without ever removing them. What I would like to do is start removing items as they sell. I am not sure how to attach the file, so if you e-mail me at drenollet#supplykick.com I can send it to you. Below are the following steps:
The Sales tab includes the sales data for the items. I would like to take this data and be able to copy and paste it in a sheet in our Inventory Managment file in excel (a separate file, but I included a sample in the "Database" sheet).
I then need to just use a VLOOKUP formula and the Catalog data to get the Product ID instead of the SKU. (I can do this.)
Then use the copied data in the Sales Tab that is in the Inventory Management file and move the corresponding rows out of the Database file/sheet to the Sold Items sheet.
A few thoughts on specifics:
I want to make sure all the quantities are right. (e.g.1 if we purchased two of an item and only one sold - reducing the quantity in the Database sheet from two down to one.) (e.g.2 If we purchased an item two different times at two different prices and both were purchased in one sale, I would want to make sure both of the rows are moved out of the database).
If you have any thoughts on making sure the quantities are right, let me know. Maybe we need to set all the purchase quantities to one and copy the purchase of a multiple quantity of items X number of times for each one that was purchased.
Would love your input on how to cross this bridge! Let me know if you would like to see the sample file and I can directly e-mail it to you!
Best Regards,
Don Renollet
The best way to do this is to have a sheet called Movements
then you have just rows of entries like
A B C D
----------------------------------------
prodID Movement type Qty Date
123 Purchase 5 08/01/15
789 Sale 2 07/01/15
123 Return 1 06/01/15
456 Sale 1 05/01/15
789 Purchase 10 04/01/15
456 Purchase 5 03/01/15
123 Sale 2 03/01/15
123 Return 1 02/01/15
123 Sale 1 02/01/15
123 Purchase 10 01/01/15
Then at anytime excel can calculate whats in stock using sumifs or similar
=SUMIFS(C:C,A:A,"123",B:B,"Purchase") - Sumif(C:C,A:A,"123",B:B,"Sale")) + Sumif(C:C,A:A,"123",B:B,"Return"))
You should never remove rows from a database like this, you can always do a stock take every so often and restart the database with 1 entry for each item, but aways store the old data elsewhere.
Try not to mix price with quantity if possible, if you need to manage price , consider using a moving average price (MAP)

Multiple entries with the same reference in a table with SQL

In a unique table, I have multiple lines with the same reference information (ID). For the same day, customers had drink and the Appreciation is either 1 (yes) or 0 (no).
Table
ID DAY Drink Appreciation
1 1 Coffee 1
1 1 Tea 0
1 1 Soda 1
2 1 Coffee 1
2 1 Tea 1
3 1 Coffee 0
3 1 Tea 0
3 1 Iced Tea 1
I first tried to see who appreciated a certain drink, which is obviously very simple
Select ID, max(appreciation)
from table
where (day=1 and drink='coffee' and appreciation=1)
or (day=1 and drink='tea' and appreciation=1)
Since I am not even interested in the drink, I used max to remove duplicates and keep only the lane with the highest appreciation.
But what I want to do now is to see who in fact appreciated every drink they had. Again, I am not interested in every lane in the end, but only the ID and the appreciation. How can I modify my where to have it done on every single ID? Adding the ID in the condition is also not and option. I tried switching or for and, but it doesn't return any value. How could I do this?
This should do the trick:
SELECT ID
FROM table
WHERE DRINK IN ('coffee','tea') -- or whatever else filter you want.
group by ID
HAVING MIN(appreciation) > 0
What it does is:
It looks for the minimum appreciation and see to it that that is bigger than 0 for all lines in the group. And the group is the ID, as defined in the group by clause.
as you can see i'm using the having clause, because you can't have aggregate functions in the where section.
Of course you can join other tables into the query as you like. Just be carefull not to add some unwanted filter by joining, which might reduce your dataset in this query.

SELECT datafields with multiple groups and sums

I cant seem to group by multiple data fields and sum a particular grouped column.
I want to group Person to customer and then group customer to price and then sum price. The person with the highest combined sum(price) should be listed in ascending order.
Example:
table customer
-----------
customer | common_id
green 2
blue 2
orange 1
table invoice
----------
person | price | common_id
bob 2330 1
greg 360 2
greg 170 2
SELECT DISTINCT
min(person) As person,min(customer) AS customer, sum(price) as price
FROM invoice a LEFT JOIN customer b ON a.common_id = b.common_id
GROUP BY customer,price
ORDER BY person
The results I desire are:
**BOB:**
Orange, $2230
**GREG:**
green, $360
blue,$170
The colors are the customer, that GREG and Bob handle. Each color has a price.
There are two issues that I can see. One is a bit picky, and one is quite fundamental.
Presentation of data in SQL
SQL returns tabular data sets. It's not able to return sub-sets with headings, looking something a Pivot Table.
The means that this is not possible...
**BOB:**
Orange, $2230
**GREG:**
green, $360
blue, $170
But that this is possible...
Bob, Orange, $2230
Greg, Green, $360
Greg, Blue, $170
Relating data
I can visually see how you relate the data together...
table customer table invoice
-------------- -------------
customer | common_id person | price |common_id
green 2 greg 360 2
blue 2 greg 170 2
orange 1 bob 2330 1
But SQL doesn't have any implied ordering. Things can only be related if an expression can state that they are related. For example, the following is equally possible...
table customer table invoice
-------------- -------------
customer | common_id person | price |common_id
green 2 greg 170 2 \ These two have
blue 2 greg 360 2 / been swapped
orange 1 bob 2330 1
This means that you need rules (and likely additional fields) that explicitly state which customer record matches which invoice record, especially when there are multiples in both with the same common_id.
An example of a rule could be, the lowest price always matches with the first customer alphabetically. But then, what happens if you have three records in customer for common_id = 2, but only two records in invoice for common_id = 2? Or do the number of records always match, and do you enforce that?
Most likely you need an extra piece (or pieces) of information to know which records relate to each other.
you should group by using all your selected fields except sum then maybe the function group_concat (mysql) can help you in concatenating resulting rows of the group clause
Im not sure how you could possibly do this. Greg has 2 colors, AND 2 prices, how do you determine which goes with which?
Greg Blue 170 or Greg Blue 360 ???? or attaching the Green to either price?
I think the colors need to have unique identofiers, seperate from the person unique identofiers.
Just a thought.