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
Related
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)
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';
I have a question regarding splitting rows based on column value
My example data set is :
id ExpenseType Price
------------------------
1 Car 100
2 Hotel 50
I want to split rows those have some Expense Types such as Car into two rows . Others should remain as one row.
First row Price *70
Second Row Price *30
Returned dataset should be
id ExpenseType Price
-----------------------
1 Car 70
1 Car 30
2 Hotel 50
Thanks for your answers in advance
If you want to split more expense types than car you could use:
WITH r AS (
SELECT 'Car' AS ExpenseType, 0.7 AS Ratio
UNION SELECT 'Car' AS ExpenseType, 0.3 AS Ratio
-- add more ExpenseTypes/Ratios here
)
SELECT
t.id,
t.ExpenseType,
t.Price * ISNULL(r.Ratio, 1.0) AS Price
FROM
your_table t
LEFT OUTER JOIN r ON t.ExpenseType = r.ExpenseType
A simple way uses union all:
select id, expensetype, price
from t
where expensetype <> 'Car'
union all
select id, expensetype, price * 0.7
from t
where expensetype = 'Car'
union all
select id, expensetype, price * 0.3
from t
where expensetype = 'Car';
This is not the most efficient method. For that, a cross apply with filtering logic is better:
select t.id, v.*
from t cross apply
(values (NULL, price), ('Car', price * 0.3), ('Car', price * 0.7)
) v(expensetype, price)
where v.expensetype = t.expense_type or
v.expensetype <> 'Car' and t.expense_type is null;
A less simple way is to use an OUTER APPLY
CREATE TABLE YourSampleData
(
Id INT IDENTITY(1,1) PRIMARY KEY,
ExpenseType VARCHAR(30) NOT NULL,
Price INT NOT NULL DEFAULT 0
);
INSERT INTO YourSampleData
(ExpenseType, Price) VALUES
('Car', 100)
,('Hotel', 50)
,('Gold', 1)
;
SELECT Id, ExpenseType
, COALESCE(a.Price, t.Price) AS Price
FROM YourSampleData t
OUTER APPLY
(
SELECT Price * Perc AS Price
FROM (VALUES
('Car',0.3E0), ('Car',0.7E0)
,('Gold',1.618E0)
) AS v(ExpType, Perc)
WHERE t.ExpenseType = v.ExpType
) a
GO
Id | ExpenseType | Price
-: | :---------- | ----:
1 | Car | 30
1 | Car | 70
2 | Hotel | 50
3 | Gold | 1.618
db<>fiddle here
I ran into a similar need, here is my solution.
Problem statement:
My organization is switching from an in-house build system to a third-party system. Numerical values in the original system surpassed the value size that the destination system could handle. The third-party system will not allow us to increase the field size, as a result we need to split the data up into values that do not surpass the field size limit.
Details:
Destination system can only support values under 1 billion (can include a negative sign)
Example:
DROP TABLE IF EXISTS #MyDemoData /* Generate some fake data for the demo */
SELECT item_no = 1, item_description = 'zero asset', amount = 0 INTO #MyDemoData
UNION SELECT item_no = 2, item_description = 'small asset', amount = 5100000
UNION SELECT item_no = 3, item_description = 'mid asset', amount = 510000000
UNION SELECT item_no = 4, item_description = 'large asset', amount = 5100000000
UNION SELECT item_no = 5, item_description = 'large debt', amount = -2999999999.99
SELECT * FROM #MyDemoData
DECLARE #limit_size INT = 1000000000
DROP TABLE IF EXISTS #groupings;
WITH
max_groups AS
(
SELECT max_groups=100
)
,groups AS
(
SELECT 1 AS [group]
UNION ALL
SELECT [group]+1
FROM groups
JOIN max_groups ON 1=1
WHERE [group]+1<=max_groups
)
,group_rows AS
(
SELECT 0 AS [row]
UNION ALL
SELECT [row]+1
FROM group_rows
JOIN max_groups ON 1=1
WHERE [row]+1<=max_groups
)
,groupings AS
(
SELECT [group],[row]
FROM group_rows
CROSS JOIN groups
WHERE [row] <= [group]
)
SELECT * INTO #groupings FROM groupings;
WITH /* Split out items that are under the limit and over the limit */
t1 AS /* Identify rows that are over the limit and by how many multiples over it is */
(
SELECT
item_no
, item_description
, amount
, over_limit = FLOOR(ABS(amount/#limit_size))
FROM #MyDemoData
)
SELECT /* select the items that are under the limit and do not need manipulated */
item_no
, item_description
, amount = CAST(amount AS DECIMAL(16,2))
FROM t1
WHERE ABS([amount]) < #limit_size
UNION ALL /* select the items that are over the limit, join on the groupings cte and calculate the split amounts */
SELECT
item_no
, item_description
, [Amount] = CAST(
CASE
WHEN row != 0 THEN (#limit_size-1) * ([amount]/ABS([amount]))
ELSE (ABS([amount]) - (t1.over_limit * #limit_size) + t1.over_limit) * ([amount]/ABS([amount]))
END AS DECIMAL(16,2))
FROM t1
JOIN #groupings bg ON t1.over_limit = bg.[group]
WHERE ABS([amount]) >= #limit_size
ORDER BY item_no
Good morning; I have two tables that I am trying to work with to develop a single query with subquery and having issues if someone could help.
First Table - [MPA_Desc] - There is more data I parsed for example
MPAID Color Model Side
1 085 x1 R
2 777 x1 R
3 085 x1 L
4 777 x1 L
Second Table - [Paintsched] - There is more data I parsed for example
Lot MPAID Amount
1 1 100
2 2 250
3 4 100
4 2 100
I am trying to get this as my query result:
Color R L
085 100 0
777 350 100
This is the query and subquery I am using, It's incomplete and doesn't have the "LH" calculations in it because I want to get the RH right first:
Select distinct(mp.Color), rh.RH
from MPA_Desc MP
right join (Select MPA_Desc.MPAID, MPA_Desc.Color, nullif(sum(qty),0) as RH from PaintSched inner join MPA_Desc on PaintSched.MPAID = MPA_Desc.MPAID
where side = 'r' group by MPA_Desc.MPAID,MPA_Desc.Color) RH
ON mp.MPAID = rh.MPAID
where Model = 'x1'
But this however gives me the following result:
Color R
085 100
085 NULL
777 350
777 Null
I know it's from my full join but I need to show the Null's as "0" and I thought nullif would work but apparently not in a subquery. Secondly I need it to just show the List of color codes by model in the original query and seperate out the sums based on RH or LH parts. Any help would be great, thank you all!
You can use PIVOT
DECLARE #MPA_Desc TABLE (MPAID INT, Color VARCHAR(5), Model VARCHAR(5), Side VARCHAR(5))
INSERT INTO #MPA_Desc VALUES
(1 , '085', 'x1', 'R'),
(2 , '777', 'x1', 'R'),
(3 , '085', 'x1', 'L'),
(4 , '777', 'x1', 'L')
DECLARE #Paintsched TABLE (Lot INT, MPAID INT, Amount INT)
INSERT INTO #Paintsched VALUES
(1 ,1 , 100),
(2 ,2 , 250),
(3 ,4 , 100),
(4 ,2 , 100)
SELECT Color, ISNULL(R,0) R, ISNULL( L,0) L FROM
( SELECT Color, Side, Amount FROM #MPA_Desc D
INNER JOIN #Paintsched P ON D.MPAID = P.MPAID ) SRC
PIVOT (SUM(Amount) FOR Side IN ([R],[L])) PVT
Result:
Color R L
----- ----------- -----------
085 100 0
777 350 100
You need conditional aggregation :
select md.Color,
sum(case when Side = 'R' then ps.amount else 0 end),
sum(case when Side = 'L' then ps.amount else 0 end)
from MPA_Desc md inner join
Paintsched ps
on ps.MPAID = md.MPAID
group by md.Color;
Try the following (Its Dynamic) -:
Declare #sql varchar(MAX),#query nvarchar(MAX)
select #sql=stuff((select distinct ', sum(case when side='''+side+''' then amount else 0 end) as '+side from [MPA_Desc] FOR XML PATH ('')), 1, 1, '' )
set #query='select color,'+#sql+' from [MPA_Desc] m join [Paintsched] n on m.MPAID=n.MPAID group by color'
EXEC sp_sqlexec #query
SQL Server 2014
I am trying to implement this query but I can’t figure out why I am not getting the result.
Here are the descriptions:
Lets say I have a table call: TableAct
Acct# Date WithdrawAmt DepositAmt
!24455 2012-11-19-00.00.00 1245.77 200.50
125577 2011-02-12-00.00.00 100.98 578.00
Another table TableCustomerOrd:
ID# COrder# CustID Ord_Description VendorType
124455 7712AS 123 1AAA Permanent
125577 9914DL 346 1BBB Partial
... UK1234 111 2HJ5 Permanent'
,,, FR0912 567 5LGY Partial
Then TableCustomerDtls:
CustID Descriptions Delivery Address ZipCode
123 1AAA_BLUESHARE SUCCESSFUL 222 Main St 97002
346 1BBB_CHASE DECLINE 40 West Side 97122
111 2HJ5_CITIBANK SUCCESSFUL ……. …….
567 5LGY_VANGURD DECLINED ---- -----
And table DelivaryFlight:
FlightOrder# FlightCustID FlightDt
7712AS 123 2011-9-29-00.00.00
9914DL 346 2010-11-2-00.00.00
UK1234 111 2012-4-1-00.00.00
FR0912 567 2012-9-11-00.00.00
I want to update TableAct on the following conditions:
TableAct. Acct# = TableCustomerOrd.ID#, AND:
TableCustomerOrd. CustID = TableCustomerDtls.CustID and at the same time, TableCustomerOrd.Ord_Descriptions field should match with TableCustomerDtls. Descriptions field anything before “_” . Therefore ‘1AAA’, ‘2HJ5’ etc. AND:
DelivaryFlight.FlightOrder# = TableCustomerOrd.COrder#, AND: DelivaryFlight.FlightCustID = TableCustomerOrd. CustID. Also TableCustomerDtls. Delivery = ‘SUCCESSFUL’ AND:
DelivaryFlight.FlightOrder# = TableCustomerOrd. COrder#
AND DelivaryFlight.FlightCustID = TableCustomerOrd. CustID
Also TableCustomerDtls. Delivery = ‘DECLINED
Then I want to compare: elivaryFlight.FlightDt > DelivaryFlight.FlightDt.
Basically I need to match table DelivaryFlight columns FlightOrder#, FlightCustID with TableCustomerOrd.
Moreover TableCustomerDtls column Delivery to ck for delivary status such as ‘DECLINED’.
And ‘SUCCESSFUL’ condition and compare ‘SUCCESSFUL’ FlightDt with ‘DECLINED’ FlightDt.
Here's my query but please help me to understand, I am sure this could be done in a better way.
The query is not working:
Update
Set …
FROM TableAct AC
Join TableCustomerOrd CustOd
ON AC.Acct# = CustOd.ID#
Join TableCustomerDtls CDtls
ON CDtls. CustID = CustOd. CustID
AND (CustOd.Ord_Descriptions =
Left(CDtls.Descriptions, LEN(rtrim(CDtls.Descriptions))))
JOIN DelivaryFlight DF
ON DF.FlightOrder# = CustOd.COrder#
AND DF.FlightCustID = CustOd.CustID
AND CDtls.Delivery = ‘SUCCESSFUL’
JOIN DelivaryFlight DF2
ON DF2.FlightOrder# = DF.COrder#
AND DF2.FlightCustID = DF.CustID
AND CDtls.Delivery = ‘DECLINED’
WHERE DelivaryFlight. FlightDt > DelivaryFlight. FlightDt
AND DepositAmt > 100
Your Help will be monumental 'cause my project due end of this week.
Thank you
If I have a complex query like this, I start by creating a "simple" select which produces only the rows to be updated.
It should also return both the update values and the pk for the updated table
It is then (relatively) straight forward to (inner) join this with the table to be updated and do the update remebering to only update matching rows by including
WHERE tblTobeUpdated.pk = SimpleSelect.pk
Hope this helps
I don't have the time to look at this in depth but I suspect you at least want to fix:
WHERE DelivaryFlight. FlightDt > DelivaryFlight. FlightDt
This is a condition that can never be met.
You probably want:
WHERE DF. FlightDt > DF2. FlightDt
it is also useful with these complex queires for an update to be able to see the records that would be updated, so I usually do something like this:
Update
Set …
--Select *
FROM TableAct AC
Then instead of running the update, I run just highlight and run the part that starts with select to see the results and don't test the update until I am sure I am selecting the records I want to select and that the values I will be replacing are correct.
Try breaking your query down, heres a query I wrote today, test each part separately
SELECT
Employee
, Reference
, Payroll
, [Hours] / 60
[Hours]
, [Days]
FROM
(
SELECT
Employee
, Reference
, Payroll
, SUM( Duration ) AS [Hours]
, AvailableID
FROM
(
SELECT
RequirerID
, Duration
, RTRIM( COALESCE(MA.MemberLastName, '')
+ ' ' + COALESCE(MA.MemberFirstName, '')
+ ' ' + COALESCE(MA.MemberInitial, '')) Employee
, COALESCE(MA.Detailref1, '') Reference
, COALESCE(MA.PayrollRef, '') Payroll
, Available.AvailableId
FROM
(
SELECT DISTINCT
RequirerID
, ShiftDate
, CAST(ShiftStart - ShiftEnd - ShiftBreak AS DECIMAL(19,2)) ShiftDuration
, Id RequirementRecordID
FROM
Requirements
WHERE
Requirements.ShiftDate BETWEEN #ParamStartDate
AND #ParamEndDate
AND RequirerID IN (SELECT ID FROM MemberDetails WHERE CompanyID = #ParamCompanyID)
)
R
INNER JOIN
ShiftConfirmed
INNER JOIN
Available
INNER JOIN
MemberDetails MA
ON Available.AvailableID = MA.ID
ON ShiftConfirmed.AvailableRecordID = Available.ID
ON R.RequirementRecordID = ShiftConfirmed.RequirementRecordID
WHERE
R.ShiftDate BETWEEN #ParamStartDate
AND #ParamEndDate
AND COALESCE(ShiftChecked, 0) BETWEEN 0 AND 1
)
ShiftDay
Group By
Employee
, Reference
, Payroll
, AvailableId
) Shifts
INNER JOIN
(
SELECT
COUNT( * ) AS [Days]
, AvailableID
FROM
(
SELECT DISTINCT
R.ShiftDate
, Available.AvailableId
FROM
(
SELECT DISTINCT
ShiftDate
, Id RequirementRecordID
FROM
Requirements
WHERE
Requirements.ShiftDate BETWEEN #ParamStartDate
AND #ParamEndDate
AND RequirerID IN (SELECT ID FROM MemberDetails WHERE CompanyID = #ParamCompanyID)
)
R
INNER JOIN
ShiftConfirmed
INNER JOIN
Available
INNER JOIN
MemberDetails MA
ON Available.AvailableID = MA.ID
ON ShiftConfirmed.AvailableRecordID = Available.ID
ON R.RequirementRecordID = ShiftConfirmed.RequirementRecordID
WHERE
R.ShiftDate BETWEEN #ParamStartDate
AND #ParamEndDate
AND COALESCE(ShiftChecked, 0) BETWEEN 0 AND 1
)
ShiftDay
Group By
AvailableId
) D
ON Shifts.AvailableID = D.AvailableID
WHERE [Hours] > 0
ORDER BY
Employee