MS Access 2010 joining with sum - sql

I am trying to combine two tables but my results are showing incorrect data from one table.
One example is my first table has the following:
PositionCode AcctUnit BudgetFTE
JDFF HRT 2
my second table does not contain any record for PositionCode=JDFF and AcctUnit=HRT however I get the following results with running the query below:
PositionCode AcctUnit BudgetFTE ActualFTE VarianceFTE
JDFF HRT 2 1 -1
sql code:
SELECT
b.PositionCode,
b.AcctUnit,
e.POSITION,
e.HM_ACCT_UNIT,
b.FTE AS BudgetFTE,
sum(e.FTE) AS ActualFTE,
sum(e.FTE) - b.FTE AS VarianceFTE
FROM
QryBudgetRollUp AS b
LEFT JOIN ActiveEmployees AS e ON
( b.PositionCode = e.POSITION ) AND
( e.HM_ACCT_UNIT = b.AcctUnit )
GROUP BY
b.PositionCode,
b.AcctUnit,
e.POSITION,
e.HM_ACCT_UNIT,
b.FTE,
e.FTE - b.FTE
sample data:
QryBudgetRollup
PositionCode AcctUnit FTE
JDFF HRT 2
VIPP HRT 1
HROPSA CMP 1
ActiveEmployees
C E CE LAST_NAME FIRST_NAME EMP PROCESS HM_ACCT_UNIT D POSITION D;P' Date SC Expr1013 AP PG HC FTE PE
2 2343 22343 Doe John FT CHRE CMP CMP HROPSA CMP;HROPSA 2/15/1999 H $20.00 $40,000.00 4 1 1 $4,000.00
2 2515 22515 Jetson George PT CHRE CMP CMP HROPSA CMP;HROPSA 4/22/2014 H $10.00 $20,000.00 2 1 0.5 $2,000.00
4 18 418 Doe Jane FT CSIS HRT HRT VIPP HRT;VIPP 11/1/2002 S $40.00 $80,000.00 7 1 1 $8,000.00
Desired Query Results
PositionCode AcctUnit BudgetFTE ActualFTE VarianceFTE
JDFF HRT 2 0 2
VIPP HRT 1 1 0
HROPSA CMP 1.5 2 -0.5

Related

Use LEFT OUTER JOIN to include NULL values in query

I want the final query to include manufacturer_id | manufacturer_name | ice_cream_id | ice_cream_name so that the print includes also those manufacturer_names, which are included in the database but do not have any ice creams (NULL ice_cream_names). Then I want the results in ascending order by manufacturer.manufacturer_id, ice_cream.ice_cream_id which i already managed to do.
Here is my sample code and sample header of the dataset I deal with:
SELECT manufacturer.manufacturer_id, manufacturer.manufacturer_name, ice_cream.ice_cream_id, ice_cream.ice_cream_name
FROM ice_cream LEFT OUTER JOIN manufacturer
ON ice_cream.manufacturer_id = manufacturer.manufacturer_id OR manufacturer.manufacturer_name IS NULL
ORDER BY manufacturer.manufacturer_id, ice_cream.ice_cream_id ASC;
manufacturer
manufacturer_id manufacturer_name country
--------------- ----------------- ----------
1 Jen & Berry Canada
2 4 Friends Finland
3 Gelatron Italy
ice_cream
ice_cream_id ice_cream_name manufacturer_id manufacturing_cost
------------ ---------------- --------------- ------------------
1 Plain Vanilla 1 1
2 Vegan Vanilla 2 0.89
3 Super Strawberry 2 1.44
4 Very plain 2 1.2
ingredient
ingredient_id ingredient_name kcal protein plant_based
------------- --------------- ---------- ---------- -----------
1 Cream 400 3 0
2 Coconut cream 230 2.3 1
3 Sugar 387 0 1
4 Vanilla extract 12 0 1
5 Strawberry 33 0.7 1
6 Dark chocolate 535 8 1
contains
ice_cream_id ingredient_id quantity
------------ ------------- ----------
1 1 70
1 3 27
1 4 3
2 2 74
2 3 21
2 4 5
3 1 60
3 3 10
3 5 30
4 2 95
4 4 5
I wonder what's the logic between FROM table1 LEFT OUTER JOIN table 2; Are those in right order? And I think I do something extra in the "ON" stage that should be done in WHERE?
You want to keep all manufacturers according to your description. Hence, that table should be the first table in the LEFT JOIN. I would also suggest using table aliases:
SELECT m.manufacturer_id, m.manufacturer_name, i.ice_cream_id, i.ice_cream_name
FROM manufacturer m LEFT JOIN
ice_cream ic
ON ic.manufacturer_id = m.manufacturer_id
ORDER BY m.manufacturer_id, ic.ice_cream_id ASC;
This doesn't require any fiddling with the ON clause, just proper use of the LEFT JOIN.

Aggregate from two tables

I have two tables
Table 'Sales Line' (SL)
Date "Entry No" Item Qty
(PK)
01/01/2018 1 ABC 1
01/02/2018 2 ABC 2
03/02/2018 3 DEF 1
04/06/2018 4 DEF 3
01/01/2019 5 DEF 1
06/06/2019 6 ABC 2
Table 'Cost Breakdown' (CB)
"SL Entry No" Cost
(FK)
1 10
1 15
2 5
3 25
4 10
4 10
5 5
6 5
6 10
Expected result:
Item Tot_Qty Tot_Cost
ABC 3 30
DEF 4 45
Note that I'm only interested on transaction in 2018 only.
How do I aggregate Tot_Qty and Tot_Cost ? Thank you
With query suggested by #GMB, the result is :
Item Tot_Qty Tot_Cost
ABC 4 30
DEF 7 45
so, line from SL will be repeated as many as correponding number of lines in CB.
You can join both tables, filter on the date, and aggregate by item:
select sl.item, sum(sl.qty) tot_qty, sum(sl.qty * cb.cost) tot_cost
from sales_line sl
inner join cost_breakdown cb on cb.sl_entry_no = sl.entry_no
where sl.date >= '20180101' and sl.date < '20190101'
group by sl.item

SQL Basket Analysis grouping query

I am trying to build a query to create a basket analysis of products based on their type grouping. They have two levels of grouping beyond the product ids.
Dept level
1
2
3
4
and buying group level
MA
M
MC
WA
W
WC
KA
KC
K
the hierarchy is
1 > W, WC
2 > M, MC
3 > K, KC
4 > MA, KA, WA
right now the query I have
Select
i.buying_group,
Sum(d.sales),
Sum(d.units),
count(distinct d.trans_nbr) transaction_count
From
sales_details d, item_data i, (select trans_nbr from sales_details where item_dept = 1 group by trans_nbr) main_group
Where
d.trans_nbr = main_group.trans_nbr
d.item_nbr = i.item_nbr
group by i.buying_group;
Right now I get the data that I need for most of the buying groups but because this is being run at the dept level it does not give me the correct basket information for W and WC. Is there a way to do this at the dept level that would show if the customer bought something from either of these groups and had the other in their basket without double counting it?
the results at the moment are something like this
buyyin_group Sum(sales) Sum(units) transaction_count
MA 100 5 4
M 75 3 3
MC 56 1 1
WA 48 3 2
W 250 6 6
WC 200 9 9
KA 164 7 5
KC 400 12 7
K 521 14 12 `

Oracle SQL Rank

I have this table as per below:
[Table A][1]
B_NUMBER_COUNTRY OUTGOING_CARRIER MINUTES
CAN A 1,045.71
CAN B 7.98
CAN C 973.52
FRA A 566.19
FRA B 521.52
FRA C 27.03
FRA D 549.14
FRA E 0.21
USA A 32.57
USA B 303.17
USA C 9,837.53
USA D 3.91
USA E 0.07
USA F 2,469.00
USA G 67.68
USA H 0.37
USA I 933.72
I need to rank b_number_country based on the sum of minutes.
In the above case, the total minutes for USA is 13K, CAN is 2K and FRA is 1.6K. So the ranking should be USA - 1, CAN - 2 and FRA - 3. By adding the rank column, it should be showing as per below:
[Table A (rank)][2]
B_NUMBER_COUNTRY OUTGOING_CARRIER MINUTES RANK
CAN A 1,045.71 2
CAN B 7.98 2
CAN C 973.52 2
FRA A 566.19 3
FRA B 521.52 3
FRA C 27.03 3
FRA D 549.14 3
FRA E 0.21 3
USA A 32.57 1
USA B 303.17 1
USA C 9,837.53 1
USA D 3.91 1
USA E 0.07 1
USA F 2,469.00 1
USA G 67.68 1
USA H 0.37 1
USA I 933.72 1
I am unable to get the right query to do this. Every attempt, it includes both b_number_country and outgoing_carrier as part of the ranking.
Edited based on comment:
You need two steps, calculate the sum of the minutes first and then rank them:
SELECT ...,
DENSE_RANK()
OVER (ORDER BY sumMinutes DESC) -- must be DENSE_RANK
FROM
(
SELECT b_number_country, interval_of_day, outgoing_carrier,
SUM (call_duration)/60 AS Minutes,
SUM (call_count) AS attempt,
SUM (answered_count) AS answered,
SUM (seizure_count) AS seizure,
SUM(start_call_count) AS Count_X,
SUM(ner_count) AS NER_COUNT,
SUM(SUM (call_duration)/60)
OVER (PARTITION BY B_NUMBER_COUNTRY) AS sumMinutes
FROM bm_archived_cdr
WHERE call_direction = 'O'
AND call_date = DATE '2016-04-21'
GROUP BY b_number_country, interval_of_day, outgoing_carrier
) dt;

PROC SQL SAS PROGRAMMING

I have the following dataset:
Name Address Bank_Account Ph_NO IP_Address Chargeoff
AJ 12 ABC Street 1234 369 12.12.34 0
CK 12 ABC Street 1234 450 12.12.34 1
DN 15 JMP Street 3431 569 13.8.09 1
MO 39 link street 8421 450 05.67.89 1
LN 12 ABC Street 1234 340 14.75.06 1
ST 15 JMP Street 8421 569 13.8.09 0`
Using this dataset I want to create the below view in SAS:
Name CountOFAddr CountBankacct CountofPhone CountOfIP CountCharegeoff
AJ 3 3 1 2 2
CK 3 3 2 2 3
DN 2 1 2 2 1
MO 1 2 2 1 2
LN 3 3 1 1 2
ST 2 2 2 2 2
The output variables indicates as follows :
-CountOfAddr : For AJ countOFAddr is 3 which means that AJ Shares its address with itself, CK and LN
-CountBankAcct : For MO count of BankAcct is 2 which means that MO Shares its bank account number with itself and ST.Similarly for variables CountofPhone and CountOfIP.
-CountChargeoff: This one is a little tricky it basically implies that AJ is Linked to CK And LN through address...and both CK and LN have been charged off so the countChargeoff for AJ is 2.
For CK the countChargeOff is 3 because it is linked with itself, MO through Bank Account, and LN/AJ through street address...so total chargeoff in CK's Network is 3(CO count of AJ+CO count of CK+CO Count of MO+CO count of LN)
I currently work as a Risk Analyst in a Financial Service Firm and the code for this problem may help us to significantly reduce funding of fraudulent accounts.
Thanks.
SQL Fiddle Demo
SELECT
Name,
(SELECT Count(Address)
FROM dataset d2
WHERE d1.Address = d2.Address
) CountOFAddr,
(SELECT Count(Bank_Account)
FROM dataset d2
WHERE d1.Bank_Account = d2.Bank_Account
) CountBankacct,
(SELECT Count(Ph_NO)
FROM dataset d2
WHERE d1.Ph_NO = d2.Ph_NO
) CountofPhone,
(SELECT Count(IP_Address)
FROM dataset d2
WHERE d1.IP_Address = d2.IP_Address
) CountOfIP,
(SELECT count(d2.Chargeoff)
FROM dataset d2
WHERE d1.name <> d2.name
and ( d1.Address = d2.Address
or d1.Bank_Account = d2.Bank_Account
or d1.Ph_NO = d2.Ph_NO
or d1.IP_Address = d2.IP_Address
)
) CountCharegeoff
FROM dataset d1
I Include the charge off calculation.
Bring all d2 <> d1.name where have any field in common. Then count that.