Basket Analysis in Powerpivot - Sum of two products' revenue - powerpivot

I want to calculate sum of two products' revenues (Product A & B) which are sold in one order whereas the guidance available to me is with respect to calculating revenues of only product b attached to product A.
Formula i am currently using is:
=
CALCULATE (
SUM ( [SALES_AMT] ),
CALCULATETABLE ( SUMMARIZE ( Sales, [GLOBAL_CONTRACT_ID] ), ALL ( Product ) ),
USERELATIONSHIP ( Sales[SKU_NUM], 'Filter Product'[Filter SKU NO] )
)

Related

SQL Pivot column values

I have tried following this and this(SQL Server specific solution) but were not helpful.
I have two tables, Product and Sale and I want to find how many products are sold on each day. But I want to pivot the table so that columns become the products name and each row will contain the amount of products sold for each day ordered by the day.
Simplified schema is as following
CREATE TABLE product (
id integer,
name varchar(40),
price float(2)
);
CREATE TABLE sale(
id integer,
product_id integer,
transaction_time timestamp
);
This is what I want
I only managed to aggregate the total sales per day per product but I am not able to pivot the product names.
select date(sale.transaction_date)
, product.id
, product.name
, count(product_id)
from sale inner join
product on sale.product_id = product.id
group by date(sale.transaction_date)
, product.id
, product.name
This is the situation so far
Please suggest.
You need pivoting logic, e.g.
select
s.transaction_date::date,
count(case when p.name = 'intelligent_rubber_clock' then 1 end) as intelligent_rubber_clock,
count(case when p.name = 'intelligent_iron_wallet' then 1 end) as intelligent_iron_wallet,
count(case when p.name = 'practical_marble_car' then 1 end) as practical_marble_car
from sale s
inner join product p
on s.product_id = p.id
group by
s.transaction_date::date;
Since your expected output aggregates by date alone, then only the transaction date should be in your GROUP BY clause. The trick used here is to take the count of a CASE expression which returns 1 when the record is from a given product, and 0 otherwise. This generates conditional counts for each product, all in separate columns. To add more columns, just add more conditional counts.

Subtract two SUM GROUP BY fields

I have two tables itemOrders and itemUsage.
itemOrders has two fields: item_number and qty_ordered
itemUsage has two fields: item_number and qty_used
I'm trying to word my SQL query so that it sums up the quantity of each item number in both tables then subtracts the totals in itemUsage from itemOrders
I've come up with this so far:
SELECT itemOrders.item_number
,(
SELECT sum(qty_ordered)
FROM itemOrders
GROUP BY itemOrders.item_number
) - (
SELECT sum(qty_used)
FROM itemUsage
GROUP BY itemUsage.item_number
) AS item_total
FROM itemOrders
INNER JOIN itemUsage
ON itemOrders.item_number = itemUsage.item_number
GROUP BY itemOrders.item_number
What happens here is that all fields come out to 0.
Example if item number "A" was showing a total quantity of 3 ordered across all instances of "A" in the itemOrders table, and only a total quantity used of 1 across all instances of "A" in the itemUsage table. The sql should show the number one in the item_total field next to 1 instance of "A" in the item_number field.
The problem is you are creating a CARTESIAN PRODUCT and repeting the values on the SUM just calculate each value separated and then LEFT JOIN both. In case no item are used COALESCE will convert NULL to 0
SELECT io_total.item_number,
order_total - COALESCE(used_total, 0) as item_total
FROM (SELECT io.item_number, sum(io.qty_ordered) as order_total
FROM itemOrders io
GROUP BY io.item_number
) io_total
LEFT JOIN (SELECT iu.item_number, sum(iu.qty_used) as used_total
FROM itemUsage iu
GROUP BY iu.item_number
) as iutotal
ON io_total.item_number = iutotal.item_number
Well it looks like you are making three queries, two separate ones, one for each sum, and one with an inner join that isn't being used.
Try
Select itemOrders.item_number, sum(itemOrders.qty_ordered - itemUsage.qty_used) as item_total
from itemOrders INNER JOIN itemUsage
On itemOrders.item_number = itemUsage.item_number
GROUP BY itemOrders.item_number

Duplicated rows in a Join Query SQL Server 2005

Dear I have the following problem. I need to get a list of products from a SQL Server 2005 database. Turns out I should first calculate the stock, which is related to many tables and then make calculations regarding other tables. The problem is that query shows me that I found records separately and have not managed to group (Investigating Google here and in whole, in addition to testing) so I decided to consult:
PD: I leave aside the products that are in the cellar [cod_bodeg] having lower value 10687 to 10000
PD2: The database belongs to a Chilean ERP and they do not provide the documentation of the model. All I know here I researched on my own.
Table Articles (ART)
NREGUIST ( ID OF ART )
Table Cellar (CHOI)
NUMREG ( ID OF CELL )
STK_FISICO ( Stock of Article in that Cell )
Table NOTDE_DB (ARTICLES SELLED)
NCODART ( INDEX to NREGUIST of ART )
cantidad ( Qty of Article that is selled in the invoice this is subtracted of the stock for calculate the qty)
Table STOCK
ARTICULO ( Index to NREGUIST of ART )
COD_BODEG ( INDEX to NUMREG of CHOI )
Table DSCTO
ID_ART ( INDEX to NREGUIST of ART )
DESCTO ( PRICE of ARTICLE )
This is my Query: What advice?
SELECT
ROUND ( ISNULL(
(
SELECT isnull( SUM( STOCK_DB.STK_FISICO ),0 )
FROM
STOCK_DB
JOIN CHOI_DB
ON STOCK_DB.cod_bodeg = CHOI_DB.numreg
WHERE
STOCK_DB.ARTICULO=ART_DB.nreguist
AND STOCK_DB.NUMEMPSTK=1
AND CHOI_DB.codigo NOT IN ('B98','B4','B6','B2')
) - ISNULL(
(
SELECT
SUM(notde_db.cantidad - notde_db.cantdesp)
FROM
notde_db,notv_db
WHERE
notde_db.ncodart=ART_DB.nreguist
AND notde_db.terminado=0
AND notv_db.numreg=notde_db.numrecor
GROUP BY notde_db.ncodart
)
,0) , 0
), 0) as DISPONIBLE,
[NOMBRE],
[NREGUIST],
[CODIGO],
[IMPUTABLE],
[XX],
[UNIDMED],
ROUND([PRECVTA], 0) AS PRECVTA,
[NIVEL1],
[NIVEL2],
[NIVEL3],
[NIVEL4],
[NIVEL5],
[NIVEL6],
[NIVEL7],
[NIVEL8],
[NIVEL9],
[CLASE1],
[CLASE2],
[CLASE3],
[CLASE4],
[ART_DISPON],
[OBS],
ROUND(ISNULL([DESCT_DB].[DESCTO],0) ,0) as PRECIO2
FROM
[STOCK_DB], [ART_DB]
LEFT JOIN
[DESCT_DB] ON ([DESCT_DB].[IDART] = [ART_DB].[NREGUIST])
WHERE
tipo = 1
AND clase2 != 'XX'
AND clase4 != 'OFF'
AND ([STOCK_DB].[cod_bodeg] != 10687 OR ( [STOCK_DB].[cod_bodeg] = 10687 AND [DESCT_DB].[DESCTO] > 10000))
ORDER BY
DISPONIBLE DESC
Thanks!

Search Invoice Tablle to find Invoices with Quantity >0 and <0

I am searching Invoice Itemized Table for Invoices with Quantity having >0 and <0. Invoice Itemized table contains details of all the items in an Invoice. How can I write a query that gives all the invoices that have Quantity of items >0 and <0.
How about something like this? This uses two queries. The first finds all the invoices with Negative Quantities. Then it APPLY's the second query to find from that list of invoices only those that also have positive quantities.
SELECT DISTINCT
PosNegInvoices.InvoiceID
FROM ItemizedInvoice AS NegInvoices
CROSS APPLY
(
SELECT
InvoiceID
FROM ItemizedInvoice
WHERE InvoiceID = NegInvoices.InvoiceID
AND Quantity > 0
) AS PosNegInvoices
WHERE NegInvoices.Quantity < 0
Here is another version that uses CTEs:
WITH NegInvoices AS
(
SELECT
InvoiceID
FROM ItemizedInvoice
WHERE Quantity < 0
),
PosInvoices AS
(
SELECT
InvoiceID
FROM ItemizedInvoice
WHERE Quantity > 0
)
SELECT DISTINCT
PosInvoices.InvoiceID
FROM NegInvoices
JOIN PosInvoices
ON NegInvoices.InvoiceID = PosInvoices.InvoiceID

MDX - Top X Sales People by Total Sales for Each Date

I'm trying to do this, but with MDX in my cube:
select
*
from
(
select
Date, SalesPerson, TotalSales, row_number() over(partition by Date order by TotalSales desc) as Num
from SalesFact as ms
) as x
where
Num < 5
order by
Date, SalesPerson, Num desc
Let's say I have a cube with these dimensions:
Date (Year, Month, Date) - date is always 1st of month
SalesPerson
The fact table has three columns - Date, SalesPerson, TotalSales - ie, the amount that person sold in that month.
I want, for each month, to see the top 5 sales people, and each of their TotalSales. The top 5 sales people can be different from one month to the next.
I am able to get the results for one month, using a query that looks like this:
select
[Measures].[TotalSales] on columns,
(
subset
(
order
(
[SalesPerson].children,
[Measures].[TotalSales],
bdesc
),
0,
5
)
) on rows
from
Hypercube
where
(
[Date].[Date].&[2009-03-01T00:00:00]
)
What I'm after is a query that puts Date and SalesPerson on rows, and TotalSales on columns.
I want to see over time each month, and for each month, the top 5 sales people, and how much they sold.
When I try to do it this way, it doesn't seem to filter / group the sales people by each date (get top 5 for each date). The values returned are all over the place and include very low and null values. Notably, the SalesPerson list is the same for each date, even though TotalSales varies a lot.
select
[Measures].[TotalSales] on columns,
(
[Date].[Hierarchy].[Date].members,
subset
(
order
(
[SalesPerson].children,
[Measures].[TotalSales],
bdesc
),
0,
5
)
) on rows
from
Hypercube
It seems that everything inside "subset" needs to be filtered by the current [Date].[Hierarchy].[Date], but using CurrentMember gives a crossjoin / axis error:
select
[Measures].[TotalSales] on columns,
(
[Date].[Hierarchy].[Date].members,
subset
(
order
(
([SalesPerson].children, [Date].[Hierarchy].CurrentMember),
[Measures].[TotalSales],
bdesc
),
0,
5
)
) on rows
from
Hypercube
Error: Executing the query ... Query (3, 2) The Hierarchy hierarchy
is used more than once in the Crossjoin function.
Execution complete
I've tried several variations of the last query with no luck.
Hopefully the answers will be helpful to others new to MDX as well.
I eventually found out how to do what I was looking for. The solution revolved around using the Generate function, and starting with the basic example on MSDN and modifying the dimensions and measure to be the ones in my cube got me going in the right direction.
From http://msdn.microsoft.com/en-us/library/ms145526.aspx
Is there a better way?
Also, be wary of trying to refactor sets into the with block. This seems to change when the set is evaluated / change its scope and will change the results.
with
set
Dates as
{
[Date].[Hierarchy].[Date].&[2009-02-01T00:00:00],
[Date].[Hierarchy].[Date].&[2009-03-01T00:00:00],
[Date].[Hierarchy].[Date].&[2009-04-01T00:00:00]
}
select
Measures.[TotalSales]
on columns,
generate
(
Dates,
topcount
(
[Date].Hierarchy.CurrentMember
*
[SalesPerson].Children,
5,
Measures.[TotalSales]
)
)
on rows
from
Hypercube