Get MAX value of a group for each month TSQL - sql

I have a TSQL query which gives a max value of the trend data for the given result set. I would like to get this data based on each month's result. (I have a datetime column in the result set ). If I select data for three months it has to give this vaules for each month. Right now it looks for the max values and give the same result for all the months.
Below is the expression i use to get the trend result. It's part of select statement with number of other columns.
select col1, col2, sampledatecollected, (Select MAX(AvailMemSlope) FROM SlopeCTE) * MetricID + (Select MAX (AvailMemIntercept) FROM InterceptCTE) AS AvailMemTrend
I think i might need to do something like this but given the expression i'm little confused as to how to get the desired results
select name, max(value)
from tbl1
group by name
CPUTrend id the data i get from the expression i specified in the first query.
sample data:
Date AVGCPU MAXCPU CPUTrend
8/22/2016 20 40 44
8/23/2016 20 40 44
8/24/2016 20 40 44
8/25/2016 20 40 44
9/22/2016 20 50 44
9/23/2016 20 50 44
9/24/2016 20 50 44
Expected result:
Date AVGCPU MAXCPU CPUTrend
8/22/2016 20 40 32
8/23/2016 20 40 32
8/24/2016 20 40 32
8/25/2016 20 40 32
9/22/2016 20 50 44
9/23/2016 20 50 44
9/24/2016 20 50 44
Right now all i get is 44 as it's the maximum value.

I think you just want a subquery:
with t as (
select col1, col2, sampledatecollected,
(Select MAX(AvailMemSlope) FROM SlopeCTE) * MetricID +
(Select MAX (AvailMemIntercept) FROM InterceptCTE) AS AvailMemTrend
from ?? -- the SQL in your question is incomplete
)
select year(sampledatecollected), month(sampledatecollected),
max(AvailMemTrend)
from t
group by year(sampledatecollected), month(sampledatecollected)
order by year(sampledatecollected), month(sampledatecollected);

Related

Display rows where multiple columns are different

I have data that looks like this. Thousands of rows returned, but this is just a sample.
Most days have the same numbers in them, but some do not. Note that ID 1 and 5 have identical numbers every day.
ID
Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
1
26
26
26
26
26
26
26
2
44
44
30
30
44
44
44
3
55
55
55
55
80
90
55
4
12
12
43
43
43
43
43
5
36
36
36
36
36
36
36
I'd like to only return rows where the days of the week have different numbers.
In this case, the only IDs returned should be 2, 3 & 4.
What would I want this query to look like?
Thanks!
One idea that should work in most RDBMS (with some syntax tweaks) is the following.
This is SQL Server compatible: pivot the days into rows and count the distinct values and filter accordingly:
select id
from t
cross apply (
select Count(distinct d) from (
values(sunday),(monday),(tuesday),(wednesday),(thursday),(friday),(saturday)
)d(d)
)d(v)
where d.v>1

table name t 10 20 30 40 want output as 10 30 50 70 in sql

t 10 20 30 40
output 10 30 50 70
One method of doing this is a cumulative sum with a window function:
select col,
sum(col) over (order by col
rows between 1 preceding and current row
)
from t;

Calculate fixed Cost/day for multiple services on same date

Desired Output table T with Calculated Cost column:
SvcID Code ID Date Mins Units Cost
1 3000 15 4/4/2016 60 10 70
2 3000 17 4/4/2016 45 10 0
3 3000 15 5/2/2016 30 10 70
4 3000 18 5/2/2016 60 10 0
5 3000 10 5/2/2016 30 10 0
6 4200 16 2/1/2016 60 4 60
7 4200 9 2/1/2016 30 2 30
Query for calculating and displaying:
SELECT
...
,CASE
WHEN Code=4200 THEN Units*15
WHEN Code=3000 THEN ?
END AS Cost
FROM ...
WHERE Code IN ('3000','4200')
GROUP BY ....;
Cost should be a total of 70 for all services offered on same date for Code 3000, irrespective of number of services offered. No relation between Minutes and Units for this Code for calculating Cost.
One way could be to calculate cost as 70 for any one service and make the remaining services cost 0 for same date. Can this be done in the CASE statement?
Any better way to achieve this?
You need to Investigate Window functions MSDN.
Your case would become something like this:
-- New select statament
SELECT
...
,CASE
WHEN Code=4200 THEN Units*15
WHEN Code=3000 THEN ( CASE WHEN DuplicateNum = 1 THEN 70 ELSE 0 END )?
END AS Cost
FROM(
-- Your current query (with case statement removed) and ROW_NUMBER() function added
SELECT
..., ROW_NUMBER() OVER( PARTITION BY Code, Date ORDER BY ID ) AS DuplicateNum
FROM ...
WHERE Code IN ('3000','4200')
GROUP BY ....
) AS YourCurrentQuery;

transpose column to row oracle

I have a query returned value in this form (query return more than 50 columns).
1-99transval 100-200transval 200-300transval ... 1-99nontransval 100...
50 90 80 67 58
For a row value. I want these details to be converted into columns and take the following shape:
Range Transval NonTransval
1-99 50 67
100-200 90 58
In pure SQL, it will need a lot of coding because you will have to manually put the range as there is no relation between the values and the range at all. Had there been a relationship, you could use CASE expression and build the range dynamically.
SQL> WITH DATA AS
2 (SELECT 50 "1-99transval",
3 90 "100-200transval",
4 80 "200-300transval",
5 67 "1-99nontransval",
6 58 "100-200nontransval",
7 88 "200-300nontransval"
8 FROM dual
9 )
10 SELECT '1-99' range,
11 "1-99transval" transval,
12 "1-99nontransval" nontransval
13 FROM DATA
14 UNION
15 SELECT '100-200' range,
16 "100-200transval",
17 "100-200nontransval" nontransval
18 FROM DATA
19 UNION
20 SELECT '200-300' range,
21 "200-300transval",
22 "200-300nontransval" nontransval
23 FROM DATA;
RANGE TRANSVAL NONTRANSVAL
------- ---------- -----------
1-99 50 67
100-200 90 58
200-300 80 88
From Oracle database 11g Release 1 and above, you could use UNPIVOT
SQL> WITH DATA AS
2 (SELECT 50 "1-99transval",
3 90 "100-200transval",
4 80 "200-300transval",
5 67 "1-99nontransval",
6 58 "100-200nontransval",
7 88 "200-300nontransval"
8 FROM dual
9 )
10 SELECT *
11 FROM DATA
12 UNPIVOT( (transval,nontransval)
13 FOR RANGE IN ( ("1-99transval","1-99nontransval") AS '1-99'
14 ,("100-200transval","100-200nontransval") AS '100-200'
15 ,("200-300transval","200-300nontransval") AS '200-300'));
RANGE TRANSVAL NONTRANSVAL
------- ---------- -----------
1-99 50 67
100-200 90 58
200-300 80 88
Above, in your case you need to replace the WITH clause with your existing query as a sub-query. You need to include other columns in the UNION.
In PL/SQL, you could (ab)use EXECUTE IMMEDIATE and get the "range" by extracting the column names in dynamic sql.
Although, it would be much better to modify/rewrite your existing query which you have not shown yet.
If you are using Oracle 11g version then you can use the UNPIVOT feature.
CREATE TABLE DATA AS
SELECT 50 "1-99transval",
90 "100-200transval",
80 "200-300transval",
67 "1-99nontransval",
58 "100-200nontransval",
88 "200-300nontransval"
FROM dual
SELECT *
FROM DATA
UNPIVOT( (Transval,NonTransval) FOR Range IN ( ("1-99transval","1-99nontransval") as '1-99'
,("100-200transval","100-200nontransval") as '100-200'
,("200-300transval","200-300nontransval") as '200-300'))
http://sqlfiddle.com/#!4/c9747/3/0

Select Only one row per user and date

i want to select only one row per user and date
so if the data like this
ID User Date
25 3597 2014-09-04 13:37:12.953
26 2100 2014-09-04 13:37:29.820
27 3597 2014-09-04 13:38:12.953
28 2100 2014-09-04 13:38:29.820
29 3597 2014-09-05 13:40:12.953
30 2100 2014-09-05 13:40:29.820
the result should be 4
The result should be 4
If all you need is the count, in SQL, you can use COUNT(DISTINCT), like this:
SELECT COUNT(DISTINCT User, Date) FROM MyTable
In LINQ, you can use GroupBy followed by Count:
int cnt = src.Items.GroupBy(item => new {i.User, i.Date}).Count();