SQL Server: inner join running total - sql

I'm doing some work on a SQL Server 2008 database (before partition) and trying to get my head running totals using inner joins. I've followed a few online tutorials but I can't get the desired results.
This is the underlying data...
Compdate count
------------------
2 198
3 29
4 22
5 27
6 31
9 18
10 16
11 22
12 26
etc...
and I need to add a running total column.
This is the query I've created so far...
select
t1.Compdate,
t1.count,
Sum(t2.count) as 'Total'
from
DB_KpiTr_Remo_CumComp_TV t1
inner join
(select count, compdate
from DB_KpiTr_Remo_CumComp_TV
where Month like 'l%') t2 on t1.Count >= t2.Count
and t1.Compdate = t2.Compdate
where
t1.Month like 'l%'
group by
t1.Compdate, t1.count
order by
t1.Compdate
select Compdate, count
from DB_KpiTr_Remo_CumComp_TV t1
But all I'm getting back is the exact same numbers in my total column...
Compdate count Total
-------------------------
2 198 198
3 29 29
4 22 22
etc...
I've tried several combinations of joins and I get several combinations of results but not the one I'm looking for - what am I missing here?

You can use apply:
select u.*, u2.running_count
from underlying u outer apply
(select sum(u2.count) as running_count
from underlying u2
where u2.compdate <= u.compdate
) u2

Related

How to find duplicate combinations of columns across two tables in SQL?

I am attempting to find duplicates across two tables which are identified as a combination of five different columns. The tables have one similar column in common. My table structure and relevant columns look like the following:
order_item_tbl
EVENT_KEY
ORDER_KEY
ORDER_NBR
14
82
1
14
82
2
14
82
3
14
82
1
invoice_tbl
EVENT_KEY
CUSTOMER_KEY
BOOTH_KEY
14
41
12
14
41
12
I've tried this query so far and everything is duplicated more than expected:
SELECT OI.ORDER_NBR AS ORDER_NBR, COUNT(*) AS COUNT
FROM ORDER_ITEM_TBL OI
JOIN INVOICE_TBL I
ON I.EVENT_KEY = OI.EVENT_KEY
WHERE OI.EVENT_KEY = '14' AND OI.ORDER_KEY = '82'
AND I.BOOTH_KEY = '12' AND I.CUSTOMER_KEY = '41' AND OI.ORDER_NBR in (1,2,3)
GROUP BY OI.ORDER_NBR
HAVING COUNT(*) > 1
Based on this dataset I would expect to receive the following result:
ORDER_NBR
COUNT
1
2
However this is the result I'm seeing:
ORDER_NBR
COUNT
1
6
2
2
3
2
Any ideas on what I'm doing wrong here?
group by ORDER_NBR alone must give you the results i reckon as you have only ORDER_NBR in select .
The same query will not execute in posgres , as psql requires columns in group by to be in select or in aggregate funcations

How to grouping with distinct or group max sql

i have date like this Data
id name period difference
6172 A 6 10
6172 A 3 10
10099 AB 12 24
10099 AB 6 24
10099 AB 3 24
10052 ABC 12 26
10052 ABC 6 26
10052 ABC 3 26
9014 ABCD 12 21
9014 ABCD 6 21
9014 ABCD 3 21
how to get result like this
id name period difference
6172 A 6 10
10099 AB 12 24
10052 ABC 12 26
9014 ABCD 12 4
i try with distinct on (id), but the result like this
id name period difference
6172 A 6 10
10099 AB 6 24
10052 ABC 6 26
9014 ABCD 6 4
The query you want looks something like:
SELECT DISTINCT ON (id) *
FROM Data
ORDER BY id, period DESC;
Demo
This is probably the most efficient way to write your query on Postgres. Note that DISTINCT ON syntax does not support more than one column in the ON clause. The above logic happens to work here assuming that id would uniquely identify each group (that is, that id would always be unique). If not, then we might have to resort to using ROW_NUMBER with a partition over id and name.
using max()
select id, name, t2.period, difference from tableA t1
inner join
(select id, max(period) as period from tableA
group by id) t2 on t2.id = t1.id
using distinct()
select distinct id, name, t2.period, difference from tableA
it seems you need just max()
select id,name,max(period),max(difference)
from table group by id,name
Though i have not found difference=4 in your sample data but you used that on output,so i guessed its your typo
Use max()
select id, name, max(period), difference from tablename
group by id, name,difference
You can try my code:
SELECT
id, name, max(period), difference
FROM
data_table
group by id, name,difference
order by name
This is a demo link http://sqlfiddle.com/#!17/9ab8d/2

Update a column in the same query as it is to be made in?

In SQL Server, I am trying to create a temp table then join based on the unique index key criteria set forth, organizing them based on their system numbers, it looks a little something like this:
SELECT DISTINCT
t1.[SysNr] AS [oldSysNr], t1.[SysNr] AS [newSysNr],
t1.[Year], t1.[WorkTm], t1.[AMSTC],
t1.[AJCC], t1.[ShifNum], t1.[FMN]
INTO
#TEMPTABLE
FROM
AppData.SCHED AS t1
JOIN
AppData.SCHED AS tS ON t1.ShifNum = tS.ShifNum
AND t1.WorkTM = tS.WorkTM
AND t1.FMN = tS.FMN
WHERE
t1.Year = 2019;
This will essentially give me the old records needed by the oldSysNr column as the year is the param I am looking at. However, I need to update the newSysNr column in the same query, no separate query to update. Is there any way that this can be achieved? I only know of doing update as a separate query.
Here is the data that is produced from the query:
oldSysNr NewSysNr Year WorkTm AMSTC AJJC SHIFNUM FMN
-----------------------------------------------------------
24 24 2019 3 WVB GH 9 YUBMS
25 25 2019 3 BMS MJ 8 YUBMS
26 26 2019 3 BMS PP 8 MJUNL
27 27 2019 4 ZMG MJ 5 MJUNL
28 28 2019 5 BR OP 3 COLHP
Here are the results that are desired:
oldSysNr NewSysNr Year WorkTm AMSTC AJJC SHIFNUM FMN
-----------------------------------------------------------
24 57 2019 3 WVB GH 9 YUBMS
25 58 2019 3 BMS MJ 8 YUBMS
26 59 2019 3 BMS PP 8 MJUNL
27 60 2019 4 ZMG MJ 5 MJUNL
28 61 2019 5 BR OP 3 COLHP
As mentioned, the param it is looking at is the year, and given that, the entire idea is that it would update NewSysNr provided that it was given the same join statement but it would be another year like 2020. Help in any given way on this issue is greatly appreciated.
You should be able to nest a subquery in the FROM clause. In other words, instead of selecting columns x,y,z from the table itself, you can replace the table name with a query which uses an updated WHERE clause.
So in this case it would look something like this: (Note: you may need to adjust the aliasing in the subquery...I'm just lazy. Also, you don't need to select all the columns in the subquery. The query in parenthesis is the subquery)
SELECT DISTINCT
tS.[SysNr] AS [newSysNr], t1.[oldSysNr]
t1.[Year], t1.[WorkTm], t1.[AMSTC],
t1.[AJCC], t1.[ShifNum], t1.[FMN]
INTO
#TEMPTABLE
FROM
(SELECT DISTINCT
t1.[SysNr] AS [oldSysNr]
t1.[Year], t1.[WorkTm], t1.[AMSTC],
t1.[AJCC], t1.[ShifNum], t1.[FMN]
FROM
AppData.SCHED AS t1
JOIN
AppData.SCHED AS tS ON t1.ShifNum = tS.ShifNum
AND t1.WorkTM = tS.WorkTM
AND t1.FMN = tS.FMN
WHERE
t1.Year = 2018)
AS t1
JOIN
AppData.SCHED AS tS ON t1.ShifNum = tS.ShifNum
AND t1.WorkTM = tS.WorkTM
AND t1.FMN = tS.FMN
WHERE
t1.Year = 2019;

How to fill in the gaps in a query of totals with zeroes?

I have a table with data like this
picks
20
20
20
18
17
12
12
9
9
This is the table but I need to get result like this.
Picks Count
20 3
19 0
18 1
17 1
16 0
...up to
1 12
How can we write query to get zero totals for data which doesn't exist in the table?
Arun
Use a subquery to generate all the numbers and then outer join it to your table.
with nos as ( select level as pick_id
from dual
connect by level <= 20 )
select nos.pick_id
, count(*)
from nos
left outer join picks
on nos.pick_id = picks.id
group by nos.pick_id
order by nos.pick_id desc ;

Multiple AVG in single SQL query

I've searched for adding multiple AVG calculations and have found a few entries, however I'm having to join another table and the examples of that are scarce.
closest answer I can find is this
but it deals with dates and no joins
here are my tables:
indicators:
StandardScore IndicatorID NID DID
0.033333 7 1 1
0.907723 9 1 1
0.574739 26 1 1
0.917391 21 1 1
.....
indexindicators:
IndexID IndicatorID
1 7
1 26
2 21
3 7
4 9
4 21
4 7
5 9
.......
My goal is to get the average for each IndexID (indexindicators) related to NID/DID (indicators) combination
a query to retrieve a single value would be
SELECT AVG(StandardScore) FROM `indicators` INNER JOIN indexindicators ON indicators.IndicatorId=indexindicators.IndicatorId WHERE nid=1 AND did=1 AND indexindicators.IndexId=1
ultimately there will be 6 (indexID) averages which then have to be rounded then * by 100 (should I do that part with PHP?)
This seems like such a simple query, but i just can't seem wrap my mind around it.
Thanks in advance for your help!
SELECT nid, did, indexid, 100.0 * AVG(StandardScore)
FROM 'indicators'
INNER JOIN 'indexindicators'
ON indicators.IndicatorId=indexindicators.IndicatorId
group by nid, did, indexid