Create an Access expression using multi-value Count() data - sql

The data I have is in a few tables. Table 1 has:
[invoice] (key),
[invoice total], and
[associated assets] (multi-value linked to [assets] in table 2).
Table two includes:
[Assets] (key), and
other asset data fields.
What I need to do is take the invoice total and divide it by the number of assets that go into that price to determine the cost of each asset. I have used the count() function in a query to get the number of assets for each invoice, but I can't seem to use the data anywhere else.
I have created another query to use the expression
= [invoice total]/count([associated assets]
In queries, I keep getting an aggregate error and can't seem to make this work. I would like for the expression result to populate a field in table 1. I need help either setting up a working query to pull the data from, or a form item that will pull the data and auto-populate the field.

For a table named [Invoices]
invoice invoice total associated assets
------- ------------- -----------------
1 $3.00 bicycles
2 $5.00 bicycles, ham
3 $1.00
where [associated assets] is a multi-value lookup field against the table [Assets]
AssetID AssetName
------- ---------
1 bicycles
2 ham
The following query
SELECT
i.invoice,
i.inv_tot AS [invoice total],
i.assetCount,
IIf(i.assetCount=0, NULL, i.[invoice total]/i.assetCount) AS avgCostPerAsset
FROM
(
SELECT
Invoices.invoice,
Min(Invoices.[invoice total]) AS inv_tot,
Count(Invoices.[associated assets].Value) AS assetCount
FROM Invoices
GROUP BY Invoices.invoice
) i
produces the following result
invoice invoice total assetCount avgCostPerAsset
------- ------------- ---------- ---------------
1 $3.00 1 3
2 $5.00 2 2.5
3 $1.00 0

Related

POSTGRESQL - Finding specific product when

I've attempted to write a query but I've not managed to get it working correctly.
I'm attempting to retrieve where a specific product has been bought but where it also has been bought with other products. In the case below, I want to find where product A01 has been bought but also when it was bought with other products.
Data (extracted from tables for illustration):
Order | Product
123456 | A01
123457 | A01
123457 | B02
123458 | C03
123459 | A01
123459 | C03
Query which will return all orders with product A01 without showing other products:
SELECT
O.NUMBER
O.DATE
P.NUMBER
FROM
ORDERS O
JOIN PRODUCTS P on P.ID = O.ID
WHERE
P.NUMBER = 'A01'
I've tried to create a sub query which brings back just orders of product A01 but I don't know how to place it in the query for it to return all orders containing product A01 as well as any other product ordered with it.
Any help on this would be very grateful.
Thanks in advance.
You can use conditional SUM to detect if one ORDER group have one ore more 'A01'
CREATE TABLE orders
("Order" int, "Product" varchar(3))
;
INSERT INTO orders
("Order", "Product")
VALUES
(123456, 'A01'),
(123457, 'A01'),
(123457, 'B02'),
(123458, 'C03'),
(123459, 'A01'),
(123459, 'C03')
;
SELECT "Order"
FROM orders
GROUP BY "Order"
HAVING SUM(CASE WHEN "Product" = 'A01' THEN 1 ELSE 0 END) > 0
I appreciated Juan's including the DDL to create the database on my system. By the time I saw it, I'd already done all the same work, except that I got around the reserved word problem by naming that field Order1.
Sadly, I didn't consider that either of the offered queries worked on my system. I used MySQL.
The first one returned the A01 lines of the two orders on which other products were ordered too. I took Alex's purpose to include seeing all items of all orders that included A01. (Perhaps he wants to tell future customers what other products other customers have ordered with A01, and generate sales that way.)
The second one returned the three A01 lines.
Maybe Alex wants:
select *
from orders
where Order1 in (select Order1
from orders
where Product = 'A01')
It outputs all lines of all orders that include A01. The subquery makes a list of all orders with A01. The first query returns all lines of those orders.
In a big database, you might not want to run two queries, but this is the only way I see to get the result I understood Alex wanted. If that is what he wanted, he would have to run a second query once armed with output from the queries offered, so there's no real gain.
Good discussion. Thanks to all!
Use GROUP BY clause along with HAVING like
select "order", Product
from data
group by "order"
having count(distinct product) > 1;

SQL treat two entries as one

I have a table with stock codes and quantity sold, but I would like to treat 2 different stock codes as one, the reason being is that one is imported and the other one locally produced but are the same product,
lets say
Product A - Imported, Stock code is abc123
Product A - Local, Stock code is aimp563
I want to sum over the quantity sold but treat the same product with and an imported stock code and local stock code as one. Is this possible?
Okay this is what I have
tbe table looks like
Product | StockCode | QtySold
Product A - Local | prdA001loc | 100
Product A - Imported | prdAImp7Z4 | 150
SELECT Product, SUM(QtySold) FROM tblA GROUP BY StockCode, Product
But this will just return the table as is. I would like this output:
Product | QtySold
Product A | 250
I believe that you need to update your DB schema to have reflect this information however if you need some naive solution you can use the following statement
SELECT substring(product, 1 , charindex('-',product)), SUM(QtySold)
FROM tblA GROUP BY substring(product, 1 , charindex('-',product))
note that the above statement assuming that all your products name will be similar to what is mentioned inside your question

Count Unique Occurrences PowerPivot

I am new to PowerPivot and DAX formulas. I assume that what I am trying to do is very basic and it has probably been answered somewhere, I just don't know what to search on it find it.
I am trying to determine the percent of sales people who had a sale in a given quarters. I have two tables, one that lists the sales people and one that list all the sales for a quarter. For example
Employee ID
123
456
789
Sales ID - Emp ID - Amount
135645 ---- 123 ----- $50
876531 ---- 123 ----- $127
258546 ---- 123 ----- $37
516589 ---- 789 ----- $128
998513 ---- 789 ----- $79
As a result, the pivot table would look like this:
Emp ID - % w/ sales
123 -------- 100%
456 -------- 0%
789 -------- 100%
Total ------- 66%
If you can point me to a post where this has been addressed or let me know the best way to address this I would appreciate it. Thank you.
Here's a simple way of doing this (assuming table names emps and sales):
=IF (DISTINCTCOUNT ( sales[Emp ID] ) = BLANK (),
0,
DISTINCTCOUNT ( sales[Emp ID] )
)
/ COUNTROWS ( emps )
The IF() is only required to ensure that people who haven't made a sale appear in the Pivot. All the actual formula is doing is dividing the number of sales rows by the number of employee rows.
Jacob
You'll need to remove the text that begins with --. I wanted to describe what the DAX is doing. This may not do what you want because it only factors the employees in the context. E.x.: If the user filtered out all employees that didn't have sales, should the grand total be 100% or 66%? For the former, you'll need to use the ALL DAX function and the below DAX does the latter. I'm very new to DAX so I'm sure there's a better way to do what you want.
=IF
(
-- are we processing 1 employee or multiple employees? (E.x.: The grand total processes multiple employees...)
COUNTROWS(VALUES(employee[Employee ID])) > 1,
--If Processing multiple employees do X / Y
-- Where X = The number of employees that have sales
-- Where Y = The number of employees selected by the user
COUNTROWS(FILTER(employee, NOT(ISBLANK(CALCULATE(COUNT(sales[Sales ID])))))) / COUNTROWS(employee),
-- If processing single employee, return 0 if they have no sales, and 1 if they have sales
IF
(
ISBLANK(CALCULATE(COUNT(sales[Sales ID]))),
0,
1
)
)

Joining a table to two one-to-many relationship tables in SQL Server

Happy Friday folks,
I'm trying to write an SSRS report displaying data from three (actually about 12, but only three relevant) tables that have akward relationships and the SQL query behind the data is proving difficult.
There are three entities involved - a Purchase Order, a Sales Order, and a Delivery. The problem is the a Purchase Order can have many sales orders, and also many deliveries which are NOT linked to the sales orders...that would be too easy.
Both the Sales Order and Delivery tables can be linked to the Purchase Order table by foreign keys and an intermediate table each.
I need to basically list Purchase Orders, a list of sales orders and a list of deliveries next to them, with NULLs for any fields that aren't valid so that'll give the required output in SSRS/when read by a human, ie, for a purchase order with 2 sales orders and 4 delivery dates;
PO SO Delivery
1234 ABC 05/10
1234 DEF 09/10
1234 NULL 10/12
1234 NULL 14/12
The above (when grouped by PO) will tell the users there are two sales orders and four (unlinked) delivery dates.
Likewise if there are more SOs than deliveries, we need NULLs in the Delivery column;
PO SO Delivery
1234 ABC 03/08
1234 DEF NULL
1234 GHI NULL
1234 JKL NULL
Above would be the case with 4 SOs and one delivery date.
Using Left Outer joins alone gives too much duplication - in this case 8 rows, as it gives 4 delivery dates for each match on the sales order;
PO SO Delivery
1234 ABC 05/10
1234 ABC 09/10
1234 ABC 10/12
1234 ABC 14/12
1234 DEF 05/10
1234 DEF 09/10
1234 DEF 10/12
1234 DEF 14/12
It's fine that the PO column is duplicated as SSRS can visually group that - but the SO/Delivery fields can't be allowed to duplicate as this can't be got rid of in the report - if I group the column in SSRS by SO then it still spits out 4 delivery dates for each one.
The only situation our query works nice is when there is just one SO per PO. In that case the single PO and SO numbers are duplicated together for x deliveries and can both be neatly grouped in SSRS. Unfortunately this is a rare occurence in the data.
I've thought of trying to use some sort of windowing function or CROSS APPLY but both fall down as they will repeat for every PO number listed and end up spitting out too much data.
At the point of thinking this just isn't set-based enough to be doable in SQL, I know the data is horrible..
Any help much appreciated.
EDIT - basical sqlfiddle link to the table schemas. Omitted many columns which aren't relevant. http://sqlfiddle.com/#!2/5ba16
Example data...
Purchase Order
PO_Number Style
1001 Black work boots
1002 Green hat
1006 Red Scarf
Sales Order
Sales_order_number PO_number Qty Retailer
A100-21 1001 15 Walmart
A100-22 1001 29 Walmart
A200-31 1006 1000 Asda
Delivery
Delivery_ID Delivery_Date PO_number
1543285 10/05/2014 1001
1543286 12/05/2014 1001
1543287 17/05/2014 1001
1543288 21/05/2014 1002
If you assign row numbers to the elements in salesorders and deliveries, you can link on that.
Something like this
declare #salesorders table (po int, so varchar(10))
declare #deliveries table (po int, delivery date)
declare #purchaseorders table (po int)
insert #purchaseorders values (123),(456)
insert #salesorders values (123,'a'),(123,'b'),(456,'c')
insert #deliveries values (123,'2014-1-1'),(456,'2014-2-1'),(456,'2014-2-1')
select *
from
(
select numbers.number, p.po, so.so, d.delivery from #purchaseorders p
cross join (Select number from master..spt_values where type='p') numbers
left join (select *,ROW_NUMBER() over (partition by po order by so) sor from #salesorders ) so
on p.po = so.po and numbers.number = so.sor
left join (select * , ROW_NUMBER() over (partition by po order by delivery) dor from #deliveries) d
on p.po = d.po and numbers.number = d.dor
) v
where so is not null or delivery is not null
order by po,number

Aggregating results for all versions of a slowly changing dimension

I am looking to aggregate values for all versions of a slowly changing dimension. Here is a simplified explanation of the problem.
I have a Product dimension and this dimension has an attribute called ProductGroup.
Products from time to time change ProductGroups.
The Product dimension is a slowly changing dimension, and the change being when it moves between ProductGroups. The Product dimension has a ProductKey and a ProductBusinessKey.
The ProductKey is the unique key within the dimension and ProductBusinessKey is the key from main booking system.
The ProductBusinessKey(PBK) is unique to a product and will never change.
A simplified structure of the dimension and fact tables are
I've used the following abbreviations
PK - ProductKey
PBK - ProductBusinessKey
PG - ProductGroup
Dimension Table
PK PBK Name PG
1 1 Prod1 ProductGroup1
2 1 Prod1 ProductGroup2
3 2 Prod2 ProductGroup1
Fact Table
PK Revenue
1 100
2 100
3 100
I want to generate a report that will display total revenue for all version of the product dimension
i.e.
Prod1 Prod2
200 100
At the the moment he mdx I am using is
SELECT
[ProductDimension].[Product].Children On Columns
FROM
TheCube
WHERE
[Measures].[Revenue]
And this is generating the following results
Prod1 Prod1 Prod2
100 100 100
I was wondering how I could structure a query to return the results as
Prod1 Prod2
200 100
Any help is much appreciated.
The easiest way would be to create an attribute that has a key of either the ProductBusinessKey, then use that in your query.
If you use the SUM(..) on the [Revenue] measure over time from your time dimension it will show the desired results.