Conditional Sum Based on Count - sql

I have reviewed the various 'Conditional Sum' questions in the forum and none quite match what I'm trying to do:
In the database, there is Date, Store#, Item#, and %Total Sales. In some cases, the same item# for the same date may be given more than one value for %Total Sales. (For some reason this is a valid business scenario that happens rarely, but it happens.)
In that situation only, the requirement is to sum the two values together into one line. So if Item# 123 has a line with a value of .05%, and another line with a value of .08%, I need to sum those two values into one line for Item #123 that has a %Total of .13%. ONLY when an item has more than one percentage assigned, those percentages should be summed. Otherwise, if an item# has only one percentage value assigned, we just want to see that value.
I cannot figure out how to do this. Basically, I would like to implement logic that would work like this:
SELECT Date, Store#, Item#,
CASE WHEN Count(%Total Sales) >1 THEN Sum(%Total Sales)
ELSE %Total Sales
END
FROM (some tables and joins)
GROUP BY Date, Store#, Item#
However, I'm not sure how to craft it so that I don't get a syntax error (this query produces errors).
Any help would be appreciated.
Thank you!

Provided you group by Date, Store#, Item# the only values that return multiple lines are those with multiple values for Total Sales of the same item on the same date.
Therefore grouping the items should be sufficient.
SELECT Date, Store#, Item#, Sum(%Total Sales)
FROM (some tables and joins)
GROUP BY Date, Store#, Item#

Why don't you make an update instead of entering a new value in the table.
Rather than manipulating of the data after insertions.
I believe this is a better idea that you can check for the existing date and update the percentage at that moment itself.
Is it not possible?

Related

Google Sheets Query Function. How can I get only Unique or Distinct Rows?

I am trying to answer a question on a case using the Query function on Google Sheets and am stuck on a particular problem.
I need to get the total number of unique orders per year. I used the formula below and managed to get the total orders per year.
=QUERY(raw_data!$A$1:$U$9995, "select YEAR(C), COUNT(B) group by YEAR(C)", 1)
Where column C is the date and B is the order_id.
The problem is that this returns a total of 9994 orders and includes duplicates of the same order. For example, if a customer purchased 3 different products, they would each be given a line in the database and would count as 3 of the 9994 orders. However, they all have the same order_id.
I need to get the number of unique orders per year. I know this number is 5009 since I did some manual research through Excel, but wanted to find that same total, separated by year, using the Query Function since this is a case to test my SQL Knowledge.
Is this possible? Does the Query Function have a way to get the count for unique order_ids? Thank you very much for your help!
See if this helps
=QUERY(UNIQUE(raw_data!$B$1:$C$9995), "select YEAR(Col2), COUNT(Col1) where Col2 is not null group by YEAR(Col2)", 1)

Need to perform some not so straight forward data processing in Access 2010

I have a table in Access that is setup like the one in the photo. What I need to do is this:
For each part no, I want to sum the total Qty for each month and type (Ordered and Demand). Then I need to cap the qty in the rows where the type is = to Orders to the value of the Qty where the type is = to Orders, when the sum of the Qty for Ordered is greater than Demand. Let me try to explain it another way.
I want to look at a subset of the master data, in this case the subset is by part no (rows with identical part numbers). For this subset I want to have two sets of sums. 1. The sum of qty with type = Ordered AND 2. a sum of qty with type = Demand. If the sum for Ordered is greater than demand, I want to change the Qty for Ordered to be the value of the Qty for Demand.
Essentially, the business reason is that for reporting purposes the total Qty for Ordered shouldn't be more than Demand in a given month, for a part number.
Looking at the photo, the rows in red will need to change because the sum of the qty is 30, which is greater than the sum of qty for the green rows (25). The red rows qty should be changed to 20 and 5 to match the green rows.
Whew, hope this made sense because it is hard to explain. I have tried many things for a couple weeks now, and I am a bit fuzzy on the details so I will just give a high level. Ok so what have I tried:
I have tried to join the table to iself, using part no (and date I believe) to join on, but that doesn't work because the sum would somehow be incorrect sometimes.
Pivot the table, using the transform and pivot functions in Access but it's important for me to keep the individual dates in tact and when I pivoted it I had to roll it up on a month basis. This gives me the row structure I need to make the changes but I don't know how to get back the original date format after I am done.
I am guessing I need some VBA code that loops through each part no, but I am not big on VBA code and I don't have much time to learn it. Any suggestions? I know this is long winded but its a complicated problem (at least for me). Thanks in advance.

SQL DateDiff Syntax

I have a homework problem that I'm having a lot of trouble with... I don't expect the answer and I truly want to learn it. Could somebody help me out with the syntax?
Problem:
For each Sales Order, show how many days it took to ship the order in order by the longest order, then by Sales Order Number. Display Sales Order Number and the number of days to ship. Include the orders that have not yet shipped.
So far I have:
SELECT SalesOrder.SalesOrderNumber,
DATEDIFF (d, MIN(SalesOrder.OrderDate), MAX(Shipment.ShipmentDate)) AS "DaysToShip"
FROM SalesOrder, Shipment
GROUP BY SalesOrder.SalesOrderNumber;
Sometimes it's helpful to see an intermediate form of your query to evaluate if it's providing the correct data at some stage.
Consider the following query, pulled from your example minus some elements:
SELECT SalesOrder.SalesOrderNumber, SalesOrder.OrderDate, Shipment.ShipmentDate
FROM SalesOrder, Shipment
You should observe the results of this query and see how they differ from what you expect. In this case, you haven't indicated how SalesOrder and Shipment are related. The result will be many more rows than there are orders, with each SalesOrder related to each and every other Shipment record (a cross-join).
Once you provide the correct join condition and achieve the desired results at that stage, try adding in aggregation (GROUP BY, MIN, MAX) and test that form of your query. Finally, when you're convinced that you have the correct inputs, add in DATEDIFF and you'll have your final query.
SELECT SalesOrder.SalesOrderNumber,
DATEDIFF (d, MAX(SalesOrder.OrderDate), MAX(Shipment.ShipmentDate)) AS "DaysToShip"
FROM SalesOrder, Shipment
GROUP BY SalesOrder.SalesOrderNumber;

summing up only certain values in column based on name in ssrs reports

By default, the SUM - sums up all the column values. But in my case, i am having a report which is grouped by Name. A name can have single offer with multiple start date's. So, a report has to display each entry for all different start date i.e Same name, offer, players only difference is the date. So for ex, when you sum up the players, only one entry per name needs to taken into account. Because, even though it has multiple start date, other entries are same and duplicated.
The expected result should be like,
The offer cost $10 refers to same $10, so it should be added only once. Similarly for players, etc., But i need the display as shown above, each entries should be shown.
How to solve this?
If all you want to do is avoid aggregating the value in the group total row, as in your example, just remove the aggregation from the expression, i.e. change:
=Sum(Fields!Players.Value)
to:
=Fields!Players.Value
This just returns the first Players value in the Scope - since it's the same value for every row this should be fine.
If you need to further aggregate this value to something like a grand total row, you have a couple of options.
For 2008R2 and above, you can use nested aggregates as an expression in the report - something like:
=Sum(Max(Fields!Players.Value,"MyGroup"))
For 2008 and below, you will need to add the aggregate value to each row in the Dataset and use this without aggregation in the report as required.
I haven’t worked with SSRS much but if this was a regular SQL query you would have to group by date range.
Try adding start date column and check if you can add another group by on top of what you already have.
It would be useful if you can provide more details here like table schema you use for retrieving the data.

Oracle function for scoring date intervals, inverse of months_between

I have a set of (employeeId, planId, coverageMonth, contractId) keys. Sometimes there are two or more (contractId)s for each (employeeId, planId, coverageMonth) i.e.
1,1,'1-Jan-2011','contract0'
1,1,'1-Feb-2011','contract0'
1,1,'1-Mar-2011','contract0'
1,1,'1-Apr-2011','contract0'
1,1,'1-May-2011','contract0'
1,1,'1-Jun-2011','contract0'
1,1,'1-Jun-2011','contract1'
1,1,'1-Jul-2011','contract1'
1,1,'1-Aug-2011','contract1'
1,1,'1-Sep-2011','contract1'
1,1,'1-Oct-2011','contract1'
1,1,'1-Nov-2011','contract1'
I've gotten the month having duplicate contractIds in one month via
...
group by employeeId, planId, coverageMonth
having count(distinct contractId) > 1
I've also expanded these keys out to (employeeId, planId, coverageMonth, contractId) via EXISTS (or IN).
I'm trying to find the best contractId for the each duplicates month record.
I want to find all months around the duplicate contract month and give each a score (the closer the month is, the higher the score, the farther out it is, the lower the score).
I want to sum the scores and the highest score decides which contractId is to be used in the duplicate month.
Problem is that the months_between() returns small values for near months and large values
for far months. I need the inverse of this.
Is there a way to set scores on other month records so that if a month is closer, it has
a better score? That way, when I aggregate/sum the scores, the best score (closest and largest clump of months) gets to determine the definitive contractId for the
month with duplicate contractIds.
I'm working in SQL / Oracle.
Any suggestions?
You could use 1/months_between() or SOME_HUGE_VALUE-months_between()
Anyway, you might want to look into analytic functions looks like you have a problem that analytic functions are made for.