double right join query [closed] - sql

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 months ago.
Improve this question
i have this table
declare #table table(year int, code int, import decimal(5,2))
insert into #table values
(2019,390107,10.00),
(2021,390107,175.00),
(2022,390107,102.00),
(2022,470101,101.00),
(2022,53015101,140.00)
i want to make a query that returns the import for each year and for each code contained in the following tables (return import = 0 where there is no record for a specific combination of year and code):
declare #years table (year int)
insert into #years values
(2018),
(2019),
(2020),
(2021),
(2022)
declare #codes table (code int)
insert into #codes values
(390107),
(470101),
(470103),
(471103),
(53010101),
(53015101)
i tried with somethig like that:
select
y.year,
c.code,
isnull(t.import,0)
from #table t
right join #years y on t.year = y.year
right join #codes c on t.code = c.code
the query does not return errors (is not a problem of using create Vs declare, nor a a problem with the tables name). but i don't get the result expected:
Expected Results
Having 6 codes and 5 years I expect 30 records (one for each combination of year and code) along with the corresponding import value from "#table" for that year/code combination (or 0 if the combination is not found)
year
code
import
2018
390107
0.00
2018
470101
0.00
2018
470103
0.00
2018
471103
0.00
2018
53010101
0.00
2018
53015101
0.00
2019
390107
10.00
2019
470101
0.00
2019
470103
0.00
2019
471103
0.00
2019
53010101
0.00
2019
53015101
0.00
2020
390107
0.00
2020
470101
0.00
2020
470103
0.00
2020
471103
0.00
2020
53010101
0.00
2020
53015101
0.00
2021
390107
175.00
2021
470101
0.00
2021
470103
0.00
2021
471103
0.00
2021
53010101
0.00
2021
53015101
0.00
2022
390107
102.00
2022
470101
101.00
2022
470103
0.00
2022
471103
0.00
2022
53010101
0.00
2022
53015101
140.00

You need to cross join the Codes and Years to get every combination and then use that in the outer join
SELECT Y.year,
C.code,
ISNULL(T.import, 0) AS import
FROM #years Y
CROSS JOIN #codes C
LEFT JOIN #table T
ON T.year = Y.year
AND T.code = C.code

Related

SQLServer - Pivoting a table with Group

I am wondering if what I am trying to do is possible. I believe it is using the PIVOT function in TSQL but don't have enough experience with the PIVOT function to know where to start.
Basically I'm trying to take the following # table called #tmpbudgetdata (truncated for simplicity):
Account Description BudgetAmount Period
-------------------- ---------------------------------------------------------------------------------------------------- --------------------- --------------------
4001 Mood Embedded Account 0.00 1
4001 Mood Embedded Account 0.00 2
4001 Mood Embedded Account 0.00 3
4001 Mood Embedded Account 0.00 4
4001 Mood Embedded Account 0.00 5
4001 Mood Embedded Account 0.00 6
4001 Mood Embedded Account 0.00 7
4001 Mood Embedded Account 0.00 8
4001 Mood Embedded Account 0.00 9
4001 Mood Embedded Account 0.00 10
4001 Mood Embedded Account 0.00 11
4001 Mood Embedded Account 0.00 12
4003 DBS Music 0.00 1
4003 DBS Music 0.00 2
4003 DBS Music 0.00 3
4003 DBS Music 0.00 4
4003 DBS Music 0.00 5
4003 DBS Music 0.00 6
4003 DBS Music 0.00 7
4003 DBS Music 0.00 8
4003 DBS Music 0.00 9
4003 DBS Music 0.00 10
4003 DBS Music 0.00 11
4003 DBS Music 0.00 12
4010 Sales - Software 5040.00 1
4010 Sales - Software 0.00 2
4010 Sales - Software 6280.56 3
4010 Sales - Software 6947.93 4
4010 Sales - Software 4800.00 5
4010 Sales - Software 0.00 6
4010 Sales - Software 2400.00 7
4010 Sales - Software 2550.00 8
4010 Sales - Software 4800.00 9
4010 Sales - Software 2400.00 10
4010 Sales - Software 0.00 11
4010 Sales - Software 2400.00 12
4015 New Install Revenue 0.00 1
4015 New Install Revenue 0.00 2
4015 New Install Revenue 0.00 3
4015 New Install Revenue 3844.79 4
4015 New Install Revenue 0.00 5
4015 New Install Revenue 0.00 6
4015 New Install Revenue 0.00 7
4015 New Install Revenue 0.00 8
4015 New Install Revenue 0.00 9
4015 New Install Revenue 0.00 10
4015 New Install Revenue 0.00 11
4015 New Install Revenue 0.00 12
and turning it into something like this:
Account Description Period1 Period2 Period3 Period4 Period5 Period6 Period7 Period8 Period9 Period10 Period11 Period12
------- --------------- -------- ------- -------- ------ ------- ------- -------- ------ ------- -------- -------- --------
4001 Mood Enabled... 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
4003 Dbs Music 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
4010 Sales - Software 5040.00 0.00 6280.56 6947.93 4800.00 0.00 2400.00 2550.00 4800.00 2400.00 0.00 2400.00
...etc...
Basically just grouping via the Account column (the description is the same per account) and then taking the period values and pivoting them horizontally.
I know I could do it with a cursor and loop through but wondering if this is possible with a pivot or by other means.
Thanks in advance
I simple PIVOT should do the trick
Example
Select *
From (
Select [Account]
,[Description]
,Period = concat('Period',Period)
,[BudgetAmount]
From YourTable
) src
Pivot (sum([BudgetAmount]) for Period in ( [Period1],[Period2],[Period3],[Period4],[Period5],[Period6],[Period7],[Period8],[Period9],[Period10],[Period11],[Period12] ) ) pvt
Returns

Cumulative Total by year

So, I have the following query,
WITH yearlist AS
(
SELECT (year(getdate())+3) AS years
UNION ALL
SELECT y.years - 1 AS years
FROM yearlist y
WHERE y.years - 1 >= (YEAR(GETDATE())-10)
)
SELECT
a.years as [year],
a.CountryName as country,
ISNULL(sum(b.sales), 0) as total
FROM(
SELECT
distinct years
,g.CountryName
FROM
yearlist AS A CROSS JOIN (SELECT
CountryName, salesYear, ISNULL(sum(sales), 0) as total
FROM tblSales where
salesYear BETWEEN (year(getdate())-12) AND (year(getdate()) + 3)
,sales
,salesYear) g
) a left outer join
(SELECT
CountryName, salesYear, ISNULL(sum(sales), 0) as total
FROM tblSales where
salesYear BETWEEN (year(getdate())-12) AND (year(getdate()) + 3)
group by CountryName
,salesYear, sales
) b ON a.CountryName=b.CountryName and a.years=b.salesYear
group by a.CountryName,years
order by years
I am getting the following returned:
year country Total
---------- ---------------------------------------- -------
2009 France 0.00
2009 Japan 0.00
2009 Norway 2.30
2009 Portugal 0.00
2009 South Korea 0.00
2009 Spain 0.00
2009 Sweden 0.00
2009 United Kingdom 0.00
2009 United States 0.00
2010 France 0.00
2010 Japan 0.00
2010 Norway 0.00
2010 Portugal 0.00
2010 South Korea 0.00
2010 Spain 0.00
2010 Sweden 0.00
2010 United Kingdom 0.00
2010 United States 0.00
2011 France 0.00
2011 Japan 0.00
2011 Norway 0.00
2011 Portugal 2.00
2011 South Korea 0.00
2011 Spain 0.00
2011 Sweden 0.00
2011 United Kingdom 0.00
2011 United States 0.00
2012 France 0.00
2012 Japan 0.01
2012 Norway 0.00
2012 Portugal 0.00
2012 South Korea 0.00
2012 Spain 0.00
2012 Sweden 0.00
2012 United Kingdom 0.00
2012 United States 0.00
2013 France 0.00
2013 Japan 2.00
2013 Norway 0.00
2013 Portugal 0.00
2013 South Korea 0.00
2013 Spain 0.00
2013 Sweden 0.00
2013 United Kingdom 0.00
2013 United States 0.00
I am trying to achieve a cumulative total for each country, as the years increase. But I cant seem to get it. I've tried this:
sum(sales) over (order by salesYear rows unbounded preceding) as total
But that just filled each row with the cumulative total.
The output I desire is as follows:
year country Total
---------- ---------------------------------------- -------
2009 France 0.00
2010 France 0.00
2011 France 0.00
2009 Japan 0.00
2010 Japan 0.00
2011 Japan 0.00
2009 Norway 2.30
2010 Norway 2.30
2011 Norway 2.30
2009 Portugal 0.00
2010 Portugal 0.00
2011 Portugal 2.00
2009 South Korea 0.00
2010 South Korea 0.00
2011 South Korea 0.00
2009 Spain 0.00
2010 Spain 0.00
2011 Spain 0.00
2009 Sweden 0.00
2010 Sweden 0.00
2011 Sweden 0.00
2009 United Kingdom 0.00
2010 United Kingdom 0.00
2011 United Kingdom 0.00
2009 United States 0.00
2010 United States 0.00
2011 United States 0.00
I just cant seem to get them to individually accumulate.
You most likely need a partition by clause, too:
sum(sum(sales)) over (partition by country order by salesYear rows unbounded preceding)

How would I add both these rows together in one row with the sum of both rows

594517 2018-11-30 5.00 0.00 0.00 0.00 8.00
594517 2018-12-18 0.00 0.00 0.00 0.00 5.00
Thanks all for the reply my situation if very hard to explain with out showing the code im dealing with,Basically the fix to a huge problem would be to get many rows with different dates into one row also adding all the totals for all those row into that same one row
column is the ID, date, the rest are total for services
I have created a table called KingLove which looks like this to try out something similar to what you're explaining on my own computer:
ID date service1 service2 service3 service4 service5
----------- ---------- --------- --------- --------- --------- ---------
594517 2018-11-30 5.00 0.00 0.00 0.00 8.00
594517 2018-12-18 0.00 0.00 0.00 0.00 5.00
If I then run this query:
select max(date) as [date], sum(service1) + sum(service2) + sum(service3) + sum(service4) + sum(service5) as [sum]
from KingLove
I get the service columns summed up and the latest date as the date for the entire row. Like this:
date sum
---------- --------
2018-12-18 18.00
You could swap the max in the query for a min if you want the oldest date instead.
It is not very easy to understand what your desired outcome would be, but I hope this is what your asking.

SQL query result issue

The query is used to get balance of certain client
SELECT t.[InvoiceID], t.S_Type as Type,
t.Date, t.Debit, t.Credit, b.Balance
FROM Statement as t CROSS apply
(SELECT Balance = SUM(Debit) - SUM(Credit)
FROM Statement as x
WHERE (x.date < t.date or
x.date = t.date
) AND
x.InvoiceID = t.InvoiceID
AND x.CustID = t.CustID
) b
WHERE t.CustID ='2' and date between '2015-01-01' and '2016-01-12'
order by InvoiceID, Type desc, Date
out out i get
InvoiceID Type Date Debit Credit Balance
4 Sales Invoice 2015-06-09 520.00 0.00 520.00
4 Receipt Voucher 2016-01-04 0.00 520.00 0.00
6 Sales Invoice 2015-06-09 160.00 0.00 160.00
6 Receipt Voucher 2016-01-04 0.00 160.00 0.00
9 Sales Invoice 2015-06-09 850.00 0.00 850.00
9 Receipt Voucher 2016-01-04 0.00 850.00 0.00
13 Sales Invoice 2015-06-09 200.00 0.00 200.00
20 Sales Invoice 2015-07-11 1225.00 0.00 1225.00
176 Sales Invoice 2015-12-14 900.00 0.00 900.00
the issue is with with sales invoices # 13 20 176 its supposed to sum the debit of invoice and show in balance
so right out put should be like this
InvoiceID Type Date Debit Credit Balance
4 Sales Invoice 2015-06-09 520.00 0.00 520.00
4 Receipt Voucher 2016-01-04 0.00 520.00 0.00
6 Sales Invoice 2015-06-09 160.00 0.00 160.00
6 Receipt Voucher 2016-01-04 0.00 160.00 0.00
9 Sales Invoice 2015-06-09 850.00 0.00 850.00
9 Receipt Voucher 2016-01-04 0.00 850.00 0.00
13 Sales Invoice 2015-06-09 200.00 0.00 200.00
20 Sales Invoice 2015-07-11 1225.00 0.00 1425.00
176 Sales Invoice 2015-12-14 900.00 0.00 2325.00
I think the logic is slightly off in the subquery.
SELECT t.[InvoiceID], t.S_Type as Type,
t.Date, t.Debit, t.Credit, b.Balance
FROM Statement as t CROSS apply
(SELECT Balance = SUM(Debit) - SUM(Credit)
FROM Statement as x
WHERE x.CustID = t.CustID AND
(x.date < t.date or
x.date = t.date AND x.InvoiceID <= t.InvoiceID
)
) b
WHERE t.CustID ='2' and
date between '2015-01-01' and '2016-01-12'
ORDER BY InvoiceID, Type desc, Date;
In other words, the prioritization for the cumulative sum should be date first and then when the dates are the same, use the invoice.
This means that all your values are really being miscalculated, because each invoice is starting over (with your original logic). However, the earlier invoices are fully paid, so you don't see the issue with them.
Note: in more recent versions of SQL Server, this is much easier (and more efficient) with the cumulative sum syntax:
sum(debit - credit) over (partition by custid order by date, invoiceid)
Or, if debit and credit could take on NULL values:
sum(coalesce(debit, 0) - coalesce(credit, 0)) over (partition by custid order by date, invoiceid)

Pivoting/Transposing SQL Table [duplicate]

This question already has answers here:
SQL Server : Columns to Rows
(7 answers)
SQL Server dynamic PIVOT query?
(9 answers)
Closed 7 years ago.
Using SQL Server 2014 Management Studio, I've been trying to find a way to convert
Year Name Col1 Col2 Col3 Col4 Col5
----------------------------------------------------
2015 ABC 0.24 0.00 0.21 0.79 0.00
2015 XYZ 0.25 0.00 0.00 0.71 0.29
to
Date Name Col Value
---------------------------
2015 ABC Col1 0.24
2015 ABC Col2 0.00
2015 ABC Col3 0.21
2015 ABC Col4 0.79
2015 ABC Col5 0.00
2015 XYZ Col1 0.25
2015 XYZ Col2 0.00
2015 XYZ Col3 0.00
2015 XYZ Col4 0.71
2015 XYZ Col5 0.29
in a dynamic fashion (i.e. it should work for any table like the first one, with n number of columns)
I've been looking around at general pivot function and doesn't seem to solve my problem.