filling running total over all month although its null - sql

I have 2 tables. One only with all periods. Second with Account, Amount and period.
I want to build a View that lists Amount kumulated, period and account. Also if I don't have an fact for a period in my table should be appear the period in my view with the last amount.
select distinct
account, b.periode,
SUM(amount) OVER (PARTITION BY account ORDER BY b.periode RANGE UNBOUNDED PRECEDING)
from
fakten a
full join
perioden b on a.periode = b.periode
order by b.periode
it like this:
1 1 6
2 1 4
1 2 13
2 2 3
NULL 3 NULL
1 4 46
2 5 48
NULL 6 NULL
NULL 7 NULL
1 8 147
NULL 9 NULL
NULL 10 NULL
NULL 11 NULL
NULL 12 NULL
I need it like:
1 1 6
2 1 4
1 2 13
2 2 3
1 3 13
2 3 3
1 4 46
2 4 3
1 5 46
2 5 48
1 6 46
2 6 46
and so one...
Any ideas?

full join is not the right approach. Instead, generate the rows you want using a cross join. Then use left join and group by to do the calculation.
select a.account, p.periode,
SUM(f.amount) OVER (PARTITION BY a.account ORDER BY p.periode)
from (select distinct account from fakten) a cross join -- you probably have an account table, use it
perioden p
on a.periode = p.periode left join
fakten f
on f.account = a.account and f.periode = p.periode
group by a.account, p.periode
order by a.account, p.periode;

Related

Get max record for each group of records, link multiple tables

I seek to find the maximum timestamp (ob.create_ts) for each group of marketid's (ob.marketid), joining tables obe (ob.orderbookid = obe.orderbookid) and market (ob.marketid = m.marketid). Although there are a number of solutions posted like this for a single table, when I join multiple tables, I get redundant results. Sample table and desired results below:
table: ob
orderbookid
marketid
create_ts
1
1
1664635255298
2
1
1664635255299
3
1
1664635255300
4
2
1664635255301
5
2
1664635255302
6
2
1664635255303
table: obe
orderbookentryid
orderbookid
entryname
1
1
'entry-1'
2
1
'entry-2'
3
1
'entry-3'
4
2
'entry-4'
5
2
'entry-5'
6
3
'entry-6'
7
3
'entry-7'
8
4
'entry-8'
9
5
'entry-9'
10
6
'entry-10'
table: m
marketid
marketname
1
'market-1'
2
'market-2'
desired results
ob.orderbookid
ob.marketid
obe.orderbookentryid
obe.entryname
m.marketname
3
1
6
'entry-6'
'market-1'
3
1
7
'entry-7'
'market-1'
6
2
10
'entry-10'
'market-2'
Use ROW_NUMBER() to get a properly filtered ob table. Then JOIN the other tables onto that!
WITH
ob_filtered AS (
SELECT
orderbookid,
marketid
FROM
(
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY
marketid
ORDER BY
create_ts DESC
) AS create_ts_rownumber
FROM
ob
) ob_with_rownumber
WHERE
create_ts_rownumber = 1
)
SELECT
ob_filtered.orderbookid,
ob_filtered.marketid,
obe.orderbookentryid,
obe.entryname,
m.marketname
FROM
ob_filtered
JOIN m
ON m.marketid = ob_filtered.marketid
JOIN obe
ON ob_filtered.orderbookid = obe.orderbookid
;

T-SQL How to configure Group by so that specific values would be correctly shown

My current T-SQL query provides the following results:
Query:
WITH CTE AS
(
SELECT SubscriberID, sum(valueMB) as ValuesMB
FROM dbo.InternetNetwork
GROUP BY SubscriberID
),
CTE2 AS (
SELECT ab.planID, a.SubscriberID, MAX(ValuesMB) as MaximumValue
FROM CTE AS a
left join
Subscriber as ab on a.SubscriberID= ab.SubscriberID
GROUP BY ab.planID, a.SubscriberID
)
select *
FROM CTE2 as b
ORDER BY b.MaximumValue desc
Output:
planID | SubscriberID | MaxValue
19 1555 97536.00
18 3528 97478.00
2 4029 93413.00
Query #2:
WITH CTE AS
(
SELECT SubscriberID, sum(valueMB) as ValuesMB
FROM dbo.InternetNetwork
GROUP BY SubscriberID
),
CTE2 AS(
SELECT ab.planID, MAX(ValuesMB) as MaximumValue
FROM CTE AS a
left join
Subscriber as ab on a.SubscriberID= ab.SubscriberID
GROUP BY ab.planID
)
SELECT pl.OperatorID, MAX(b.MaximumValue) as Super
FROM CTE2 as b
left join
Plan as pl on b.planID= pl.planID
GROUP BY pl.operatorID
ORDER BY pl.operatorID
Output #2:
OperatorID | Value
1 93413.00
2 86017.00
3 97536.00
I would like to also include a subscriberID, but I'm unable to figure out a way to do so, as the only way to do it, is including in the last SELECT and adding to GROUP BY, which when done, makes a mess of a result which is not accurate.
My desired output:
OperatorID | Value | SubscriberID
1 93413.00 4029
2 86017.00 164
3 97536.00 1544
internet network data:
SubscriberID ValuesMB
1 28
1 27
2 27
2 27
2 27
3 29
3 28
3 27
3 27
4 27
4 27
4 29
Subscriber Data:
SubscriberID PersonID PlanID
1 1 3
2 2 10
3 2 6
4 3 14
5 3 1
6 4 18
7 5 5
8 5 1
9 5 9
10 5 16
11 6 13
12 6 13
13 6 20
14 6 16
15 7 4
Plan data
PlanID OperatorID
1 1
2 1
3 2
4 2
5 2
6 2
7 2
8 2
9 2
10 2
11 2
12 3
13 3
14 3
15 3
16 3
17 3
18 3
19 3
20 3
The tables are somewhat like this related InternetNetwork-> Subscriber -> Plan. InternetNetwork contains how much each Subscribed has used. Each Subscriber has Plan associated with him. Each Plan contains a different Operator, there are only three. I wish to list all three operators, the data transferred by the subscriber of the plan that has the operator and Subscriber ID.
Window functions allow you to have fields in your select along with aggregate functions. You can do something like this
;WITH CTE AS
(
SELECT I.SubscriberID,
S.PlanID,
SUM(ValuesMB) OVER(PARTITION BY i.SubscriberID)as ValuesMB
FROM dbo.InternetNetwork I
JOIN Subscriber S
ON I.SubscriberID = S.SubscriberID
),
CTE2 AS
(
SELECT p.operatorID,
a.SubscriberID,
a.ValuesMB,
ROW_NUMBER() OVER(PARTITION BY p.operatorID ORDER BY a.ValuesMB DESC) as rn
FROM CTE a
join [Plan] P
on a.planID = P.planID
)
SELECT operatorID,
ValuesMB,
SubscriberID
FROM CTE2
where rn = 1

MS Access merge two tables

I need to create a new table base on two tables. I have a database in ms access and need to migrate.
tableT tableS
ID CustID DATE Exp1 Exp2 ID CustID DATE Tem1 Tem2
-------------------------------- ---------------------------------
1 1 1/1/00 5 5 1 1 1/1/00 3 4
2 2 1/1/00 1 3 2 2 1/1/00 5 0
3 1 3/1/00 3 2 3 1 5/1/00 0 3
4 3 4/1/00 4 1 4 3 6/1/00 0 0
Desired output table tableNew:
ID CustID DATE Exp1 Exp2 Tem1 Tem2
---------------------------------------------
1 1 1/1/00 5 5 3 4
2 2 1/1/00 1 3 5 0
3 1 3/1/00 3 2
4 3 4/1/00 4 1
5 1 5/1/00 0 3
6 3 6/1/00 0 0
If I use outer join, I will not get the output I need.
Any idea or help.
You want a full join. You can emulate this in MS Access using:
select t.CustID, t.DATE, t.Exp1, t.Exp2, s.tem1, s.tem2
from TableT as t left outer join
tableS as s
on t.CustId = s.CustId and t.date = s.date
union all
select s.CustID, s.DATE, null, null, s.tem1, s.tem2
from tableS as s left outer join
tableT as t
on t.CustId = s.CustId and t.date = s.date
where t.CustId is null;

Get datetime difference group by query results in one row

I have a table Master_History with structure as
Id_History Created_Date Subscription_Type rn
21 1/22/2016 16:31:29 1 1
22 1/22/2016 16:33:11 2 2
23 1/22/2016 16:33:37 1 3
24 1/22/2016 16:33:46 2 4
25 1/22/2016 16:33:53 1 5
26 1/22/2016 16:33:57 3 6
27 1/22/2016 16:34:01 2 7
28 1/22/2016 16:34:04 1 8
29 1/22/2016 16:34:08 3 9
I want to calculate date difference with adjacent rows which i have succeeded in calculating but results are getting distributed over multiple rows
Standard Plus Premium
122 NULL NULL
NULL 35 NULL
NULL NULL 3
I need
Results in one row like
Standard Plus Premium
122 35 3
For the last row (in this Subscription_Type is 3, the date difference should also get calculated on getdate() i.e. whenever i executed my query, seconds in Premium column should get reflected each time
Query :
WITH CTE
AS (
SELECT *
,ROW_NUMBER() OVER (
ORDER BY Created_Date
) AS rn
FROM Master_History
WHERE Client_ID = 11072
)
SELECT CASE
WHEN mc.Subscription_Type = 1
THEN Sum(DATEDIFF(second, mc.Created_Date, mp.Created_Date))
END AS [Standard]
,CASE
WHEN mc.Subscription_Type = 2
THEN Sum(DATEDIFF(second, mc.Created_Date, mp.Created_Date))
END AS Plus
,CASE
WHEN mc.Subscription_Type = 3
THEN Sum(DATEDIFF(second, mc.Created_Date, mp.Created_Date))
END AS Premium
FROM CTE mc
JOIN CTE mp ON mc.rn = mp.rn - 1
GROUP BY mc.Subscription_Type
try this
select
count(Standard.*) Standard_,
count(Plus.*) Plus_,
count(Premium.*) Premium_
from
Master_History master_
left outer join Master_History Standard on Standard.Subscription_Type = 1
and master_.Subscription_Type = Standard.Subscription_Type
left outer join Master_History Plus on Plus.Subscription_Type = 2
and master_.Subscription_Type = Plus.Subscription_Type
left outer join Master_History Premium on Premium.Subscription_Type = 3
and master_.Subscription_Type = Plus.Subscription_Type
where
convert(date,master_.Created_Date) < convert(date,getdate()) and
convert(date,master_.Created_Date) < convert(date,Standard.Created_Date) and
convert(date,master_.Created_Date) < convert(date,Plus.Created_Date) and
convert(date,master_.Created_Date) < convert(date,Premium.Created_Date)

SQL Inner Join and Partitioning To obtain RowNumbers when matching

I have 2 tables. The first table 'a' the second 'b'.
I am writing a query that grabs every row in table a (there is 33 rows defined) and inner joins table b where the EnclLocation or the BackPanLoc match the Workcell in table A.
I only want a row from table B where they match based off BackPan and EnclLocation but they are not the same records. table b has a few rows of data that is assigned to the same workcell as table a. I am just trying to retrieve those additional rows and partition it.
I attached table a and table b. I also attached the desired results for this query with respect to Workcell 10 only as an example... As you can see, table B has 4 records that has either the EnclLocation or the BackPanLoc = 10. But my results only show the same DelvNumber 4 times. any help is most appreicated.
Table a
Table b
Incorrect Results
Desired Results (showing only Workcell 10 as an example)
workcell DelvNumber RowNum
1 447910-02 1
2 445710-01 1
2 445710-01 2
3 444291-01 1
3 444291-01 2
4 447910-03 1
4 447910-03 2
5 648020-01 1
6 647800-02 1
7 646920-01 1
7 646920-01 2
8 644830-4-8 1
8 644830-4-8 2
9 443990-01 1
10 645960-01-03 1
10 445710-11 2
10 445710-02 3
10 445710-09 4
Code Used
WITH ss
AS (SELECT a.*,
Row_number()
OVER(
partition BY a.workcell
ORDER BY a.workcell) AS rownum
FROM nwcurrent a
INNER JOIN nwdeliverables b
ON b.encllocation = a.workcell
OR b.backpanloc = a.workcell
WHERE ( b.status < 9
AND ( b.encllocation <> 0
OR b.backpanloc <> 0 )
OR a.delvnumber = '123' ))
SELECT *
FROM ss
copy and paste format
1 447910-02 1
2 445710-01 1
2 445710-01 2
3 444291-01 1
3 444291-01 2
4 447910-03 1
4 447910-03 2
5 648020-01 1
6 647800-02 1
7 646920-01 1
7 646920-01 2
8 644830-4-8 1
8 644830-4-8 2
9 443990-01 1
10 645960-01-03 1
10 445710-11 2
10 445710-02 3
10 445710-09 4
SQLFiddle
http://sqlfiddle.com/#!3/a8682/4
A new try...
SELECT a.workcell
,a.DelvNumber AS A_DelvNumber
,b.DelvNumber AS B_DelvNumber
,CASE WHEN a.DelvNumber<>b.DelvNumber THEN b.DelvNumber ELSE a.DelvNumber END AS DelvNumber_Resolved
,Row_number() OVER(partition BY a.workcell ORDER BY a.workcell) AS rownum
FROM NWCurrent a
INNER JOIN NWDeliverables AS b ON b.EnclLocation=a.WorkCell OR b.BackPanLoc=a.WorkCell
WHERE (b.status <9 AND (b.EnclLocation<>0 OR b.BackPanLoc<>0)OR a.DelvNumber='123')