How can I join 2 table together? - sql

I'm trying to create a join table with 2 existing tables. something like below:
This is the first table queries and looks like this
https://ibb.co/sg2MXKf
SELECT
DATEPART( week, dbo.Income.IncomeDate ) AS [Week Income],
DATEPART( YEAR, dbo.Income.IncomeDate ) AS [Year],
SUM ( dbo.Income.CardAmount ) AS [Total Card],
SUM ( dbo.Income.CashAmount ) AS [Total Cash],
SUM ( dbo.Income.TipsAmount ) AS [Total Tip],
SUM ( dbo.Income.SalaryAmount ) AS [Total Salary],
SUM ( dbo.Income.Adjustment ) AS [Total Adjustment]
FROM
dbo.Income
GROUP BY
DATEPART( week, dbo.Income.IncomeDate ),
DATEPART( YEAR, dbo.Income.IncomeDate )
ORDER BY
DATEPART(YEAR, dbo.Income.IncomeDate )
And this is the second table queries and looks like this
https://ibb.co/z8sRwpT
SELECT
DATEPART( wk, dbo.Transactions.PaymentMadeOn ) AS [Week],
COUNT (DATEPART( wk, dbo.Transactions.PaymentMadeOn )) AS [Expenses Count],
DATEPART( YEAR, dbo.Transactions.PaymentMadeOn ) AS [Year],
SUM ( dbo.Transactions.PaymentAmount ) AS [Total]
FROM
dbo.Transactions
GROUP BY
DATEPART( wk, dbo.Transactions.PaymentMadeOn ),
DATEPART( YEAR, dbo.Transactions.PaymentMadeOn )
ORDER BY
DATEPART( YEAR, dbo.Transactions.PaymentMadeOn )
What I expected is something this. Both table 1 and 2 combined, and the total expenses added.
https://ibb.co/0DbZLYV

As commented by SO folks, we cannot access the images that describe your expected results. However we understand that you are looking to JOIN the results of both queries that you are showing.
Here is how to do it : you turn each query into a subquery, and you JOIN them together on their common key fields ; in your use case, this must be Year and Week. The ORDER BY clause needs to be moved to the outer query. In the SELECT, WHERE and ORDER BY clauses, you can freely access all the fields from the subqueries, using the aliases that you defined (here A and B).
Sample code (you will have to adapt the SELECT, I cannot tell what you want it to look like) :
SELECT
A.[Week Income],
A.[Year],
A.[Total] - B.[Total Salary] AS [Balance]
...
FROM (
SELECT
DATEPART( week, dbo.Income.IncomeDate ) AS [Week Income],
DATEPART( YEAR, dbo.Income.IncomeDate ) AS [Year],
SUM ( dbo.Income.CardAmount ) AS [Total Card],
SUM ( dbo.Income.CashAmount ) AS [Total Cash],
SUM ( dbo.Income.TipsAmount ) AS [Total Tip],
SUM ( dbo.Income.SalaryAmount ) AS [Total Salary],
SUM ( dbo.Income.Adjustment ) AS [Total Adjustment]
FROM
dbo.Income
GROUP BY
DATEPART( week, dbo.Income.IncomeDate ),
DATEPART( YEAR, dbo.Income.IncomeDate )
) AS A
LEFT JOIN (
SELECT
DATEPART( wk, dbo.Transactions.PaymentMadeOn ) AS [Week],
COUNT (DATEPART( wk, dbo.Transactions.PaymentMadeOn )) AS [Expenses Count],
DATEPART( YEAR, dbo.Transactions.PaymentMadeOn ) AS [Year],
SUM ( dbo.Transactions.PaymentAmount ) AS [Total]
FROM
dbo.Transactions
GROUP BY
DATEPART( wk, dbo.Transactions.PaymentMadeOn ),
DATEPART( YEAR, dbo.Transactions.PaymentMadeOn )
) AS B ON A.[Week Income] = B.[Week] AND A.[Year] = B.[Year]
ORDER BY
A.[Year],
A.[Week Income]

Related

Pivot table & Group by

I'm using this query to get previous 12 months Sales.
SELECT *
FROM (SELECT
gp_etablissement [ETABLISSEMENT],
datename(month, dateadd(m,-1,getdate())) [Month],
COUNT(1) [Sales Count]
FROM PIECE
GROUP BY gp_etablissement,
datename(month, dateadd(m,-1,getdate()))) AS MontlySalesData
PIVOT( SUM([Sales Count])
FOR Month IN ([January],[February],[March],[April],[May],
[June],[July],[August],[September],[October],[November],
[December])) AS MNamePivot
I got this error :
Each GROUP BY expression must contain at least one column that is not
an outer reference.
I've changed many columns in the group by, but same problem.
Use the below code for eliminating the error. The pivot doesn't work with the subquery that way when the group by uses date parts.
;WITH CTE
AS
(
SELECT
gp_etablissement [ETABLISSEMENT],
datename(month, dateadd(m,-1,getdate())) [Month],
COUNT(1) [Sales Count]
FROM PIECE
GROUP BY gp_etablissement,
datename(month, dateadd(m,-1,getdate()))
)
SELECT *
FROM CTE
PIVOT( SUM([Sales Count])
FOR Month IN ([January],[February],[March],[April],[May],
[June],[July],[August],[September],[October],[November],
[December])) AS MNamePivot

Separate SELECT into multiple columns by WHERE condition without creating multiple rows caused by adding to GROUP BY

I'm trying to split SUM( trs_amt ) and SELECT it into 'trs_sum' column when trs_trust_code is either 1 or 2, and into an 'interest' column when trs_trust_code = 9. I cant seem to figure out how to do it without creating an extra row when adding trs_trust_code to the GROUP BY. I have tried a CASE in SELECT, a CASE in GROUP BY, subqueries
SELECT
trs_desk,
dsk_name,
DATEPART( YEAR, DATEADD( DAY, trs_trx_date, '1600-12-31' ) ) as 'year',
DATEPART( MONTH, DATEADD( DAY, trs_trx_date, '1600-12-31' ) ) as 'month',
COUNT( DISTINCT trs_amt ) AS 'trs_count',
SUM( trs_amt ) AS 'trs_sum',
SUM( trs_comm_amt ) AS 'trs_comm_sum'
FROM cds.trs
JOIN cds.dsk on dsk_code = trs_desk
WHERE trs_desk IN ( 'ACE' )
AND trs_trust_code IN ('1','2','9')
GROUP BY trs_desk, year, month, dsk_name
ORDER BY trs_desk ASC, year DESC, month DESC
Please use the expression case when trs_trust_code = 9 then trs_amt else 0 end in the sum. For example like this:
SELECT
trs_desk,
dsk_name,
DATEPART( YEAR, DATEADD( DAY, trs_trx_date, '1600-12-31' ) ) as 'year',
DATEPART( MONTH, DATEADD( DAY, trs_trx_date, '1600-12-31' ) ) as 'month',
COUNT( DISTINCT trs_amt ) AS 'trs_count',
SUM( case when trs_trust_code = 1 or trs_trust_code = 2 then trs_amt else 0 end ) AS 'trs_sum',
SUM( case when trs_trust_code = 9 then trs_amt else 0 end ) AS 'interest',
SUM( trs_comm_amt ) AS 'trs_comm_sum'
FROM cds.trs
JOIN cds.dsk on dsk_code = trs_desk
WHERE trs_desk IN ( 'ACE' )
AND trs_trust_code IN ('1','2','9')
GROUP BY trs_desk, year, month, dsk_name
ORDER BY trs_desk ASC, year DESC, month DESC

Average count data from pivot table - Need assistance

I am working on a little project to deliver application that pull data from database to show average of shipment made each day of the week. I have made some progress and have now script that count all of shipment but because I count them based on varchar type of column also I need solution to calculate average for each day of the week separately.
So far I end up with something as follows:
SELECT [Monday], [Tuesday], [Wednesday], [Thursday], [Friday], [Saturday], [Sunday]
FROM (
SELECT DATENAME(dw, Shipment.Date) AS DayWeek, Shipment.ID
FROM Shipment
WHERE MONTH(Shipment.Date)= MONTH(DATEADD(MONTH, DATEDIFF(MONTH, 0, 'OCTOBER 2016' ), 0)) AND
Shipment.Bur = 'GB'
) AS src
pivot (
COUNT(ID) FOR DayWeek IN ([Monday], [Tuesday], [Wednesday], [Thursday], [Friday], [Saturday], [Sunday])
) AS pvt
I appreciate much any hint or help as it is looks like I run out of ideas at the moment and can get any further to deliver right solution.
I would suggest dispensing with the pivot altogether and putting on the results in separate rows:
SELECT DayWeek, AVG(cnt)
FROM (SELECT s.Date, DATENAME(dw, s.Date) AS DayWeek, COUNT(*) as cnt
FROM Shipment s
WHERE MONTH(s.Date) = MONTH(DATEADD(MONTH, DATEDIFF(MONTH, 0, 'OCTOBER 2016' ), 0)) AND
s.Bur = 'GB'
GROUP BY s.Date
) d
GROUP BY DayWeek
ORDER BY MIN(s.Date);
I found the answer for my question by browsing through stackoverflow encountering on similar problem posted by one of the user.
SELECT [Day], SUM(q.Totals) AS "Weekly Shipment Amount", AVG(Totals) AS [Avg]
FROM
(
SELECT
w = DATEDIFF(WEEK, 0, DATE),
[Day] = DATENAME(Weekday, DATE),
Totals = COUNT(*)
FROM dbo.Shipment
--INNER JOIN FCLI (NOLOCK) ON FCLI.CCLI = FEXP.CCLI
WHERE (BUR = 'GB' AND
Shipment.Date >= '20160601' AND Shipment.Date <= '20160630')
GROUP BY
DATEDIFF(WEEK, 0, Date),
DATENAME(WEEKDAY, Date),
DATEPART(WEEKDAY, Date)
) AS q
GROUP BY [Day]
ORDER BY [DaY] ASC;

SQL Calculate Percentage in Group By

I have an SQL query that is used as the basis for a report. The report shows the amount of fuel used grouped by Year, Month and Fuel Type. I would like to calculate the percentage of the total for each fuel type, but I'm not having much luck. In order to calculate the percentage of the whole, I need to be able to get the total amount of fuel used regardless of the group it is in and I can't seem to figure out how to do this. Here is my query:
SELECT Year([DT1].[TransactionDate]) AS [Year], Month([DT1].[TransactionDate]) AS [Month], DT1.FuelType, Format(Sum(DT1.Used),"#.0") AS [Total Used],
FROM (SELECT TransactionDate, FuelType, Round([MeterAfter]-[MeterBefore],2) AS Used FROM FuelLog) AS DT1
WHERE (((DT1.TransactionDate) Between [Start Date] And [End Date]))
GROUP BY Year([DT1].[TransactionDate]), Month([DT1].[TransactionDate]), DT1.FuelType
ORDER BY Year([DT1].[TransactionDate]), Month(DT1.TransactionDate), DT1.FuelType;
I tried adding the following as a subquery but I get an error saying the subquery returns more than one result.
(SELECT Sum(Round([MeterAfter]-[MeterBefore],2)) AS Test
FROM Fuellog
WHERE Year([Year]) and Month([Month])
GROUP BY Year([TransactionDate]), Month([TransactionDate]))
Once I get the total of all fuel I will need to divide the amount of fuel used by the total amount of both fuel types. Should I be approaching this a different way?
Try this
SELECT A.[Year]
,A.[Month]
,A.[FuelType]
,A.[Total Used]
,(A.[Total Used] / B.[Total By Year Month]) * 100 AS Percentage
FROM
(
SELECT Year([DT1].[TransactionDate]) AS [Year]
, Month([DT1].[TransactionDate]) AS [Month]
, DT1.FuelType
, Format(Sum(DT1.Used),"#.0") AS [Total Used]
FROM (
SELECT TransactionDate
, FuelType
, Round([MeterAfter]-[MeterBefore],2) AS Used
FROM FuelLog
) AS DT1
WHERE (((DT1.TransactionDate) Between [Start Date] And [End Date]))
GROUP BY Year([DT1].[TransactionDate]), Month([DT1].[TransactionDate]), DT1.FuelType
ORDER BY Year([DT1].[TransactionDate]), Month(DT1.TransactionDate), DT1.FuelType
) A
INNER JOIN
(
SELECT Sum(Round([MeterAfter]-[MeterBefore],2)) AS [Total By Year Month]
, Year([TransactionDate]) AS [Year]
, Month([TransactionDate])) AS [Month]
FROM Fuellog
GROUP
BY Year([TransactionDate])
, Month([TransactionDate]))
) B
ON A.[Year] = B.[Year]
AND A.[Month] = B.[Month]
You need to join to the totals -- something like this (untested might have typos)
SELECT
Year([DT1].[TransactionDate]) AS [Year],
Month([DT1].[TransactionDate]) AS [Month],
DT1.FuelType,
Format(Sum(DT1.Used),"#.0") AS [Total Used],
(Sum(DT1.Used) / FT.Total) * 100 AS Percent
FROM (
SELECT
TransactionDate,
FuelType,
Round([MeterAfter]-[MeterBefore],2) AS Used
FROM FuelLog
) AS DT1
JOIN (
SELECT
Sum(Round([MeterAfter]-[MeterBefore],2)) AS Total
FuelType
FROM Fuellog
WHERE TransactionDate Between [Start Date] And [End Date]
GROUP BY FuelType
) FT ON DT1.FuelType = FT.FeulType
WHERE DT1.TransactionDate Between [Start Date] And [End Date]
GROUP BY Year([DT1].[TransactionDate]), Month([DT1].[TransactionDate]), DT1.FuelType, FT.Total
ORDER BY Year([DT1].[TransactionDate]), Month(DT1.TransactionDate), DT1.FuelType, FT.Total;

How to query for a value from the last month of each quarter?

SELECT YEAR(aum.AUM_Timeperiod) as Year,
DATEPART(q, aum.AUM_TimePeriod) AS Quarter,
SUM(cast(aum.AUM_AssetValue AS money)) as total_AssetValue
FROM AssetUnderManagement as aum,
LineOfBusiness
where aum.LOB_ID = LineOfBusiness.LOB_ID
and LineOfBusiness.LOB_Name = 'Asset Management'
GROUP BY YEAR(aum.AUM_Timeperiod), DATEPART(q, aum.AUM_TimePeriod);
The above query returns the value per quarter.
My question is how to change it if I want the Total_AssetValue of the last month in that quarter to be assigned to that quarter.
For eaxmple Quater 3 total_AssetValue is sum(100+200+300). but i want the quater 3 value to be 300 which is the last month value in that quater
How about:
SELECT
Year,
Quarter,
(
SELECT SUM(CAST(AUM_AssetValue AS MONEY))
FROM AssetUnderManagement
WHERE YEAR(AUM_Timeperiod) = i.Year
AND MONTH(AUM_TimePeriod) = i.LastMonthInQuarter
) AS total_AssetValue
FROM
(
SELECT
YEAR(aum.AUM_Timeperiod) AS Year,
DATEPART(q, aum.AUM_TimePeriod) AS Quarter,
MAX(MONTH(aum.AUM_TimePeriod)) AS LastMonthInQuarter
FROM
AssetUnderManagement as aum, LineOfBusiness
WHERE
aum.LOB_ID = LineOfBusiness.LOB_ID
AND LineOfBusiness.LOB_Name = 'Asset Management'
GROUP BY
YEAR(aum.AUM_Timeperiod),
DATEPART(q, aum.AUM_TimePeriod)
) AS i
Here's a version that uses a common table expression:
WITH MyData AS
(SELECT YEAR(aum.AUM_Timeperiod) AS [Year], DATEPART(q, aum.AUM_TimePeriod) AS [Quarter],
DATEPART(M, aum.AUM_TimePeriod) AS [Month],
DATEPART(M, aum.AUM_TimePeriod) - (DATEPART(q, aum.AUM_TimePeriod) - 1) * 3 AS [MonthInQtr],
SUM(CAST(aum.AUM_AssetValue AS MONEY)) AS [total_AssetValue]
FROM AssetUnderManagement AS aum, LineOfBusiness
WHERE aum.LOB_ID = LineOfBusiness.LOB_ID
AND LineOfBusiness.LOB_Name = 'Asset Management'
GROUP BY YEAR(aum.AUM_Timeperiod), DATEPART(q, aum.AUM_TimePeriod),
DATEPART(M, aum.AUM_TimePeriod), DATEPART(M, aum.AUM_TimePeriod) -
(DATEPART(q, aum.AUM_TimePeriod) - 1) * 3
)
SELECT [Year], [Quarter]
FROM MyData
WHERE MonthInQtr = 3
ORDER BY [Year], [Quarter], [total_AssetValue]
;
You can use the same CTE from above and use the following query to get your original results
SELECT [Year], [Quarter], SUM([total_AssetValue])
FROM MyData
GROUP BY [Year], [Quarter]
ORDER BY [Year], [Quarter]
;