Get datetime difference group by query results in one row - sql

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)

Related

SQL Filter Each Record By The Latest Date

I have two tables I am joining.
asset
assetid length
1 10
2 190
3 8
inspection
flag date assetid
0 2/3/2021 3
1 5/4/2022 3
1 3/19/2021 1
1 6/14/2020 2
When I join I get this
SELECT
inspection.flag,
inspection.date,
asset.assetid,
asset.length
FROM asset left join inspection on asset.assetid = inspection.assetid
GROUP BY inspection.flag, inspection.date, asset.assetid, asset.length
Flag Date AssetID Length
0 2/3/2021 3 8
1 5/4/2022 3 8
1 3/19/2021 1 10
1 6/14/2020 2 190
But I want to filter by each record that has the latest date so i can find out what the most recent flag is. Like below
Flag Date AssetID Length
1 5/4/2022 3 8
1 3/19/2021 1 10
1 6/14/2020 2 190
All the methods i have been using gives me the latest single record of all that has the latest date. Any Idea?
One option uses ROW_NUMBER:
WITH cte AS (
SELECT i.flag, i.date, a.assetid, a.length,
ROW_NUMBER() OVER (PARTITION BY a.assetid ORDER BY i.date DESC) rn
FROM asset a
INNER JOIN inspection i ON a.assetid = i.assetid
)
SELECT flag, date, assetid, length
FROM cte
WHERE rn = 1
ORDER BY assetid;
you need to use max function:
SELECT
inspection.flag,
asset.assetid,
asset.length,
max(inspection.date)
FROM asset left join inspection on asset.assetid = inspection.assetid
GROUP BY 1, 2, 3

How to multiply data to get value | Oracle |

I have 2 table Table 1 : Employee and Table 2 : Department
Below is the join condition i have used
select e.empsal,d.rate from employee e left join on department d where e.empid = d.depid
Based on d.rate the value of e.empsal should get multiple , upto join condition i was able to do after that where to add case is not getting , if you see drate value will be anything
if their are 25 drate values like : 1 2 4 6 7 9 14 36 67 8 2 4 19 11 8
It is not feasible to write that many times if conditions
case drate
if 0 then e.empsal*1
if 1 then e.empsal*10
if 2 then e.empsal*100
if 4 then e.empsal*1000
if 6 then e.empsal*1000000
...
Example : Below is the logic and its Output expected:
if d.rate value is 0 then new_empsal=e.empsal * 1
if d.rate value is 1 then new_empsal=e.empsal * 10
if d.rate value is 2 then new_empsal=e.empsal * 100
if d.rate value is 3 then new_empsal=e.empsal * 1000
will go on ...
So the new values of e.empsal should be below
EMPSAL,DRATE,NEW_EMPSAL
1200,0,1200
2345,1,23450
1678,3,1678000
2219,6,2219000000
2458,1,24580
2697,2,269700
2936,1,29360
3175,4,31750000
3414,7,34140000000
3653,2,365300
3892,1,38920
4131,1,41310
4566,0,4566
4131,4,41310000
1000,6,1000000000
345,1,3450
2345,5,234500000
1123,0,1123
990,3,990000
1100,3,1100000
345,7,3450000000
2345,2,234500
How to achieve this below output using above condition ?
Are you looking for a case expression?
select e.*,
(case d.rate
when 0 then 1 when 1 then 10 when 2 then 100 when 3 then 1000 when 4 then 10000 when 6 then 1000000
end) * e.empsal
from employee e left join
department d
on e.depid = d.depid;
Note that this fixes your syntax using where instead of on. I also changed the join condition, because matching empid to depid doesn't make much sense to me.
Or more concisely using power():
select e.*, power(10, d.rate) * e.empsal
from employee e left join
department d
on e.dep = d.depid;

Sum in case expression

I am writing a code in SQL Server 2017 Windows 10. I don't know where the issue is and I can't get the result of total in case expression.
Here is my code
select PD.PONO, PM.CURRSTATUS, PD.Qty
, case when pm.currstatus = 1 then sum(pd.qty) end TotalStock
from ppom PM
LEFT OUTER join ppod PD on pd.pono = pm.pono
where pm.pono = 15973
group by PD.PONO, PM.CURRSTATUS, PD.Qty
GO
Result is showing below
PONO CURRSTATUS Qty TotalStock
15973 1 8 8
15973 1 14 14
15973 1 25 25
While result should show the sum value
PONO CURRSTATUS Qty TotalStock
15973 1 8 47
15973 1 14 47
15973 1 25 47
Please help me in this thanks
You seem to want a window sum rather than aggregation. It would look like:
select
pd.pono,
pm.currstatus,
pd.qty,
sum(case when pm.currstatus = 1 then pd.qty else 0 end)
over(partition by pd.pono) total_stock
from ppom pm
left join ppod pd on pd.pono = pm.pono

filling running total over all month although its null

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;

complex paratition sum in postgresql

I have tables as follow:
A deliveries
delveryid clientid deliverydate
1 10 2015-01-01
2 10 2015-02-02
3 11 2015-04-08
B items in deliveris
itemid deliveryid qty status
70 1 5 1
70 1 8 2
70 2 10 1
72 1 12 1
70 3 100 1
I need to add a column to my query that gives me the qty of each part in other deliveris of the same client.
meaning that for given data of client 10 and delivery id 1 I need to show:
itemid qty status qtyOther
70 5 1 10 //itemid 70 exists in delivery 2
70 8 2 10 //itemid 70 exists in delivery 2
72 12 1 0 //itemid 72 doesn't exists in other delivery of client 11
Since I need to add qtyOther to my existing qry i'm trying to avoid using Group By as it's a huge query and if I use SUM in select I will have to group by all items in select.
This is what I have so far:
Select ....., coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid) ,0) AS qtyOther
FROM B b
LEFT JOIN A a USING
LEFT JOIN (other tables)
WHERE clientid=10 ....
This query gives me the total sum of qty per itemid for specific clientid, regardless of which delivery it is. How do I change it so it will consider the delivryid? I need something like:
coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid) FROM B where deliveryid<>b.deliveryid ,0) AS qtyOther
Any suggestions how to do that?
Note: I can NOT change the condition in WHERE.
I think you just want to subtract out the total for the current delivery:
Select .....,
(coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid), 0) -
coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid, a.deliveryid), 0)
) as qtyOther