Value as a % of row total in QlikSense - qlikview

In QlikSense i want to show value as % of row total, using:
count(-value-) / count(Total -value-)
Using the expression above gives me % of totals not row total.
For example, in the new type column, T, % should be 7935 / 8287 = 95.75% and not 13.71%
count(new_type_id) / count(Total New_Type_ID) gives me the result in attached picture

Im using the following script to recreate your data:
Load * inline [
Type, New_Type_ID, new_type_id
T , 8287 , 7935
B , 11942 , 565
C , 18233 , 674
X , 13890 , 165
P , 5515 , 0
];
And using the following expression:
Sum(new_type_id) / Sum(total <Type> New_Type_ID)
The result will show 95.75% for Type = T
The difference is in the scope of the Total qualifier. In your case Total will be called over all results/values and will yield 57 867.
Total can be "forced"/scoped to be called only over specific field(s) values:
Total <[field name here]>
From Qlik's documentation page
Update
(as pivot table and split)
Load script to achieve pivot table structure:
Load * inline [
Type, Amount
T , 8287
B , 11942
C , 18233
X , 13890
P , 5515
];
Load * Inline [
New_Type, Type, SplitAmount
T , T , 7935
B , T , 332
C , T , 12
X , T , 6
P , T , 2
T , B , 565
B , B , 11022
C , B , 302
X , B , 45
P , B , 8
];
Measures:
Units calculationSum(SplitAmount)
% calculation Sum(SplitAmount) / Sum(Total <Type> SplitAmount)

Related

BigQuery, subtract between 2 tables with the same column names

I have 2 tables in BigQuery.
The first table is user_id table, each user has many labels associated with the user (label1, label2, label3, ...). The second table is product_id table, and each product also has the same number of labels associated with it (label1, label2, label3, ...)
Table 1:
user_id, label1, label2, label3, ... (hundreds of columns)
001 , 1 , 2 , 0 , ...
002 , 2 , 0 , 1 , ...
Table 2:
product_id, label1, label2, label3, ... (hundreds of columns)
a , 0 , 3 , 1 , ...
b , 1 , 2 , 0 , ...
I'd like to write a sql script to generate the following table. The label columns are calculated by labelX in user_id table - labelX in product_id table. For example, the label1 cell for the row with user_id=001 and product_id=a is calculated by 001's label1 - a's label1 = 1-0 = 1.
user_id, product_id, label1, label2, label3, ... (hundreds of columns)
001 , a , 1 , -1 , -1 , ...
001 , b , 0 , 0 , 0 , ...
002 , a , 2 , -3 , 0 , ...
002 , b , 1 , -2 , 1 , ...
You can cross join both tables. The main query that you need to execute is :
select
a.user_id, b.product_id,
(a.label1 - b.label1) as label1,
(a.label2 - b.label2) as label2,
(a.label3 - b.label3) as label3,
...
from table1 as a
cross join table2 as b
This will require you to dynamically generate the query though based on labels. You can use programming language, or bigquery scripting as below. Make sure to replace the label count, and table names in the query.
DECLARE label_clause STRING;
SET (label_clause) = (
select as struct STRING_AGG('(a.label' || i || '-b.label'|| i ||') as label' || i, ',')
from unnest(generate_array(1,100)) i
);
EXECUTE IMMEDIATE
FORMAT("select a.user_id, b.product_id, %s from table1 as a cross join table2 as b", label_clause)

How to calculate row using different value from joined table

I need to run an update on a SQL table, using a value from a different (but almost identical) row in the same table, to show how different sales scenarios play out.
e.g.
Starting with:
ITEM, SITE, SUPPLIER, SCENARIO, SALES_VOLUME, PRICE, TOTAL_SALES
1 , A , X , S1 , 100 , 10 , 1000
2 , A , Y , S1 , 25 , 20 , 500
1 , A , X , S2 , {blank} , 20 , 0
I would like to update to show:
ITEM, SITE, SUPPLIER, SCENARIO, SALES_VOLUME, PRICE, TOTAL_SALES
1 , A , X , 1 , 100 , 10 , 1000
2 , A , Y , 1 , 25 , 20 , 500
1 , A , X , 2 , {blank} , 20 , 2000
So basically, if SCENARIO = S2, I need to recalculate using SALES_VOLUME where SCENARIO = S1
I tried the following, but it didn't work - I think because I'm trying to specify both =1 and !=1 in the same lookup.
UPDATE TABLE1
SET [TOTAL_SALES] = (t1.[PRICE] * t2.[SALES_VOLUME])
FROM TABLE1 t1
inner join TABLE1 t2
on t1.[ITEM] = t2.[ITEM]
and t1.[SITE] = t2.[SITE]
and t1.[SUPPLIER] = t2.[SUPPLIER]
and t1.[SCENARIO] = 'S1'
WHERE t1.[SCENARIO] != 'S1'
I don't think I'm too far off, but just feel I'm missing something.
Any pointers would be gratefully received. :)
You may try this -
UPDATE t1
SET [TOTAL_SALES] = (t1.[PRICE] * t2.[SALES_VOLUME])
FROM TABLE1 t1
inner join TABLE1 t2
on t1.[ITEM] = t2.[ITEM]
and t1.[SITE] = t2.[SITE]
and t1.[SUPPLIER] = t2.[SUPPLIER]
and t1.[SCENARIO] = 'S2'
WHERE t2.[SCENARIO] = 'S1';

Group by Help - Oracle SQL

How would I implement a group by to this?
Tried just grouping by everything in the select and it doesn't appear to work.
SELECT SL.ORDER_NO,
SL.HANDLING_UNIT_ID,
HUS.MANUAL_GROSS_WEIGHT,
SL.OBJVERSION,
ACCOUNTING_PERIOD_API.GET_PERIOD_DESCRIPTION(SITE_API.GET_COMPANY(SHIPMENT_API.GET_CONTRACT(HUS.SHIPMENT_ID)),
ACCOUNTING_PERIOD_API.GET_CURR_ACC_YEAR(SITE_API.GET_COMPANY(SHIPMENT_API.GET_CONTRACT(HUS.SHIPMENT_ID))),
ACCOUNTING_PERIOD_API.GET_CURR_ACC_PERIOD(SITE_API.GET_COMPANY(SHIPMENT_API.GET_CONTRACT(HUS.SHIPMENT_ID)))) ACC_DESC,
HUS.WIDTH,
HUS.HEIGHT,
HUS.DEPTH,
SL.QUANTITY * IFSAPP.HANDLING_UNIT_API.GET_TARE_WEIGHT(HUS.HANDLING_UNIT_ID, HUS.UOM_FOR_WEIGHT) TOTAL_WEIGHT_KGS,
HUS.HANDLING_UNIT_TYPE_ID CASE_NOS,
HUS.WIDTH * HUS.HEIGHT * HUS.DEPTH DIMENSIONS,
HUS.WIDTH * HUS.HEIGHT * HUS.DEPTH * 3 / 1000000 TOTAL_CUBE_BOX
FROM SHIPMENT_LINE_HANDL_UNIT SL
JOIN HANDLING_UNIT_SHIPMENT_CFV HUS
ON HUS.SHIPMENT_ID = SL.SHIPMENT_ID
JOIN SHIPMENT S
ON S.SHIPMENT_ID = SL.SHIPMENT_ID
JOIN CUSTOMER_ORDER CO
ON CO.ORDER_NO = S.ORDER_NO
WHERE SHIPMENT_API.GET_STATE(HUS.SHIPMENT_ID) = 'Completed'
AND SHIPMENT_API.GET_CONTRACT(HUS.SHIPMENT_ID) = '1314'
AND SL.HANDLING_UNIT_ID = HUS.HANDLING_UNIT_ID
AND S.SHIP_VIA_CODE = 'SEA'
AND CO.REGION_CODE = 'AM'
Expected data:
Shiptrain7 1 102 102 111x93x106 RPL111x93x106 93 111 106 3.28
Shiptrain7 1 57 57 111x93x106 RPL111x93x106 93 111 106 3.28
Shiptrain8 1 150 150 111x93x106 RPL111x93x106 93 111 106 3.28
Shiptrain8 1 2 2 35x26x33 RPL35x26x33 26 35 33 3.28
There is just one of each case, the handling unit id is associated to each case. Its bringing the actual ID rather than amount of each case which is 1. Also, this is being used in a crystal report so ignore the fields which arent needed.
You want to GROUP BY everything in the projection except the handling_unit_id, which you just want to count. You could alter the existing query, but you have a large number of derived columns which will make the GROUP BY clause complicated and brittle.
So you should wrap the existing query in another query which you can use for aggregation. Note that you must give an alias to each column in the query.
select order_no
, count(handling_unit_id) as no_of_units
, manual_gross_weight
, objversion
, acct_period_description
, acct_period
, acc_desc
, width
, height
, depth
, total_weight_kgs
, case_nos
, dimensions
, total_cube_box
from (
SELECT SL.ORDER_NO,
SL.HANDLING_UNIT_ID,
HUS.MANUAL_GROSS_WEIGHT,
SL.OBJVERSION,
ACCOUNTING_PERIOD_API.GET_PERIOD_DESCRIPTION(SITE_API.GET_COMPANY(SHIPMENT_API.GET_CONTRACT(HUS.SHIPMENT_ID)) as acct_period_description,
ACCOUNTING_PERIOD_API.GET_CURR_ACC_YEAR(SITE_API.GET_COMPANY(SHIPMENT_API.GET_CONTRACT(HUS.SHIPMENT_ID))) as acct_period,
ACCOUNTING_PERIOD_API.GET_CURR_ACC_PERIOD(SITE_API.GET_COMPANY(SHIPMENT_API.GET_CONTRACT(HUS.SHIPMENT_ID)))) ACC_DESC,
HUS.WIDTH,
HUS.HEIGHT,
HUS.DEPTH,
SL.QUANTITY * IFSAPP.HANDLING_UNIT_API.GET_TARE_WEIGHT(HUS.HANDLING_UNIT_ID, HUS.UOM_FOR_WEIGHT) TOTAL_WEIGHT_KGS,
HUS.HANDLING_UNIT_TYPE_ID CASE_NOS,
HUS.WIDTH * HUS.HEIGHT * HUS.DEPTH DIMENSIONS,
HUS.WIDTH * HUS.HEIGHT * HUS.DEPTH * 3 / 1000000 TOTAL_CUBE_BOX
FROM SHIPMENT_LINE_HANDL_UNIT SL
JOIN HANDLING_UNIT_SHIPMENT_CFV HUS
ON HUS.SHIPMENT_ID = SL.SHIPMENT_ID
JOIN SHIPMENT S
ON S.SHIPMENT_ID = SL.SHIPMENT_ID
JOIN CUSTOMER_ORDER CO
ON CO.ORDER_NO = S.ORDER_NO
WHERE SHIPMENT_API.GET_STATE(HUS.SHIPMENT_ID) = 'Completed'
AND SHIPMENT_API.GET_CONTRACT(HUS.SHIPMENT_ID) = '1314'
AND SL.HANDLING_UNIT_ID = HUS.HANDLING_UNIT_ID
AND S.SHIP_VIA_CODE = 'SEA'
AND CO.REGION_CODE = 'AM'
)
group by order_no
, manual_gross_weight
, objversion
, acct_period_description
, acct_period
, acc_desc
, width
, height
, depth
, total_weight_kgs
, case_nos
, dimensions
, total_cube_box

SQL Query returning 0 when there is data

I have the following SQL Query:
SELECT
a.IA
, a.PC
, a.LC
, a.CXPevalCnt
, ((a.IA / nullif(a.CXPevalCnt,0))*0.35) as IAcalc
, ((a.LC / nullif(a.CXPevalCnt,0))*0.5) as legacalc
, ((a.PC / nullif(a.CXPevalCnt,0))*0.15) as pccalc
, (
((a.IA / nullif(a.CXPevalCnt,0))*0.35)
+ ((a.LC / nullif(a.CXPevalCnt,0))*0.5)
+ ((a.PC / nullif(a.CXPevalCnt,0))*0.15)
) as Compliance
FROM
(
SELECT
SUM(IA) as IA
, SUM(PC) as PC
, SUM(LC) as LC
, SUM(CXPevalcount) as CXPevalCnt
FROM
tblPLOps_Data
) as A
Which returns the following data:
IA PC LC CXPevalCnt IAcalc legacalc pccalc Compliance
15 12 15 15 0.35 0.5 0 0.85
If PC is 12 and CXPevlacnt is 15 I cannot figure out why in my query when I add them together cxpevalcount nulls out but only for PC and not when used with IA or LC. I have sliced this query many different ways and can't figure out the issue
any ideas?
Because you are doing integer division. 12/15 = 0. If you want to do accurate math you need to multiply one of them by 1.0 or convert to force sql to do numeric division.
((a.PC * 1.0) / nullif(a.CXPevalCnt, 0)) * 0.15 as pccalc
You would need to do the same for your other columns as well.

Trying to Get SELECT TOP to work with Parameter in ACCESS

This is building on some code I got the other day (thanks to peterm). I am now trying to select the TOP X number of results after calculations on the query. The X can range from 1 to 8 depending on the number of results per player.
This is the code I have but I get a syntax error when I try to run it.
SELECT
PlayerID
, RoundID
, PlayedTo
, (SELECT Count(PlayerID) FROM PlayedToCalcs) AS C
, iif(
C <= 6
, 1
, iif(
C <= 8
, 2
, (
iif(
C <= 10
, 3
, (
iif(
C <= 12
, 4
, (
iif(
C <= 14
, 5
, (
iif(
C <= 16
, 6
, (
iif(
C <= 18
, 7
, (iif(C <= 20, 8, 999))
)
)
)
)
)
)
)
)
)
)
)
) AS X
FROM PlayedToCalcs AS s
WHERE PlayedTo IN (
SELECT TOP (X) PlayedTo
FROM PlayedToCalcs
WHERE PlayerID = s.PlayerID
ORDER BY PlayedTo DESC, RoundID DESC
)
ORDER BY PlayerID, PlayedTo DESC, RoundID DESC;
Here is a link http://sqlfiddle.com/#!3/a726c/4 with a small sample of the data I'm trying to use it on.
The Access db engine does not allow you to use a parameter for SELECT TOP. You must include a literal value in the SQL statement.
For example this query works correctly.
SELECT TOP 2 *
FROM tblFoo
ORDER BY id DESC;
But attempting to substitute a parameter, how_many, triggers error 3141, "The SELECT statement includes a reserved word or an argument name that is misspelled or missing, or the punctuation is incorrect."
SELECT TOP how_many *
FROM tblFoo
ORDER BY id DESC;
The reason being in SQL Server (the simulator you used in SQL Fiddle), you cannot use IIF. Try using CASE.
And there is a limitation of using 7 nested IIF in Access.