Analytical TSQL - c#

I need to produce some SQL that will show me the trend (up or down tick) in some transacitons.
Consider this table with a PlayerId and a Score
PlayerId, Score, Date
1,10,3/13
1,11,3/14
1,12,3/15
If I pull data from 3/15 I have a score of 12 with an upward trend compared to the historical data.
I did something similar in Oracle 8i about 10 years ago using some of the analytical functions like rank, however it was 10 years ago....
The results would look similar to
PlayerId, Score, Date, Trend
1,12,3/15,UP
How can I do something similar with sql azure?

This SQL:
with data as (
select * from ( values
(1,11,cast('2013/03/12' as smalldatetime)),
(1,15,cast('2013/03/13' as smalldatetime)),
(1,11,cast('2013/03/14' as smalldatetime)),
(1,12,cast('2013/03/15' as smalldatetime))
) data(PlayerId,Score,[Date])
)
select
this.*,
Prev = isnull(prev.Score,0),
tick = case when this.Score > isnull(prev.Score,0) then 'Up' else 'Down' end
from data this
left join data prev
on prev.PlayerId = this.PlayerId
and prev.[Date] = this.[Date] - 1
returns this output:
PlayerId Score Date Prev tick
----------- ----------- ----------------------- ----------- ----
1 11 2013-03-12 00:00:00 0 Up
1 15 2013-03-13 00:00:00 11 Up
1 11 2013-03-14 00:00:00 15 Down
1 12 2013-03-15 00:00:00 11 Up

Related

SQL to LINQ - Getting Wrong Results

If a user selects 07-07-2016, I want to count how many times billdays > 30 for that billdate month, for the past 12 months.
Query is this:
select COUNT(*) as 'BillsOver30' from pssuite_web.pujhaccd
where billdays>30 and DATEDIFF(month,'07-07-2016', GETDATE()) <= 13
Group By Month(billdate)
Result is this:
1784 (July)
1509 (June)
2986 (May)
2196 (etc)
5853
3994
1753
1954
869
1932
629
1673
LINQ query is:
DateStart = '07-07-2016' (from a textbox on view)
DateTime earliestDate = objdate1.DateStart.Value.AddMonths(-13);
var custQuery9 = (from m in DataContext.pujhaccds
where m.billdays > 30 &&
m.billdate >= earliestDate &&
m.billdate <= objdate1.DateStart
group m by m.billdate.Value.Month into p
select new Date1()
{
theMonth = p.Key,
theCount = p.Count()
});
Results are:
Month Count
1 1029
2 1018
3 1972
4 1519
5 2657
6 2019
7 1206
8 1023
9 761
10 1620
11 354
12 931
You can see that the LINQ query is way off.
Doesn't matter what date I put in, the result always stays the same. Rather than 12 months from starting date.
I must be writing it wrong, thanks.

How to do multiple select sum sub-queries

This is my first post so if I do anything incorrectly concerning the post please correct me.
I am creating a scoring program for a fishing competition.
I have the following tables(I am only going to list the columns of interest:
tblScores:
|Column Name|
Pk_CatchID
Fk_AnglerID
Day
Fk_FishID
Points
tblAnglers:
|Column Name|
Pk_AnglerID
Fk_BoatID
Name
tblBoats:
|Column Name|
Pk_BoatID
BoatName
Now what I want to do is create a score sheet for a whole week of competition, which is 5 days. So I have to do a sum of the scores and use the respective foreign keys to sum the scores for each boat.
This is what I have currently:
Select BoatName, " +
"Sum(tblScores.Points) AS [Day 1] " +
"from tblScores INNER JOIN tblAnglers ON tblScores.Fk_AnglerID=tblAnglers.Pk_AnglerID " +
" INNER JOIN tblBoats ON tblAnglers.Fk_BoatID=tblBoats.Pk_BoatID "
+ " where Day=1 GROUP BY BoatName
This works perfectly fine for one day, but what I would like to do is view this data in a DataGridView with columns for each day and then a total column as well.
Something like this:
|Boat Name|Day 1|Day 2|Day 3|Day 4|Day 5|Total|
|Example1 | 50 | 30 | 65 | 35 | 40 | 220 |
|Example2 | 40 | 50 | 70 | 35 | 30 | 225 |
I have tried using nested selects but I could not get this to work. I am open to suggestions on how this can be solved.
Also my other thought was to create a new table and keep these scores for each day in there(or even in the boats table) but I feel that the structure of the database would not be as good as data would be repeated. But I could be wrong.
Thank you all!
Also: I am using Visual Studio 2013 (C#) and Microsoft SQL Server 2010.
Try this:
Select
BoatName,
Sum(Case When Day = 1 Then tblScores.Points Else 0 End) AS [Day1],
Sum(Case When Day = 2 Then tblScores.Points Else 0 End) AS [Day2],
Sum(Case When Day = 3 Then tblScores.Points Else 0 End) AS [Day3],
Sum(Case When Day = 4 Then tblScores.Points Else 0 End) AS [Day4],
Sum(Case When Day = 5 Then tblScores.Points Else 0 End) AS [Day5],
Sum(tblScores.Points) As Total
From tblScores
INNER JOIN tblAnglers ON tblScores.Fk_AnglerID=tblAnglers.Pk_AnglerID
INNER JOIN tblBoats ON tblAnglers.Fk_BoatID=tblBoats.Pk_BoatID
GROUP BY BoatName
Order By BoatName
Fiddle

How to get data from the previous month result in SQL Server

I have 2 tables ms and fr.
ms contains columns pid,month, and totalsales, while fr contains pid, month, and forecast.
In both tables, each pid has 12 record based on month.
I actually want to calculate the demand where the formula is (0.3 * totalsales) + (0.7 * previous month result of forecast). The previous month result of forecast is like when the user choose pid 2 and month 2, then it will take the forecast result from month 1 as its calculation data.
I tried it already but the desired result is not returned:
select
((0.3 * totalsalesamount) + (0.7 * forecastdemand)) as demand
from
Monthlysales, forecastreorder
where
Monthlysales.P_ID = forecastreorder.Productid
and Monthlysales.P_ID = 1
and forecastreorder.Month = 2
When I execute the code above the result is based on their each forecast result. For example, when I choose pid 1, month 2, then it will take the forecast result from month 2 also. meanwhile i want it to take the forecast result from month 1 as its calculation data.
Try this to get previous month in sql
SELECT Convert(datetime, DateAdd(month, -1, Convert(date, GetDate())));
Using a similar table but with a year field, using ISNULL for no found data from previous moth, presume the previous is the month sales.
SELECT
0.3 * ms.totalsalesamount + 0.7 * ISNULL(fr.forecastdemand, ms.totalsalesamount) as demand
FROM
ms
LEFT OUTER JOIN
fr ON ms.pid = fr.pid
AND fr.month = CASE WHEN ms.month > 1 THEN ms.month - 1 ELSE 12 END
AND fr.year = CASE WHEN ms.month > 1 THEN ms.year ELSE ms.year - 1 END

Update all records using a function sql

I am looking to update a calculated sum in sql
Basically I have a table:
ImportID SeiralNumber Day Hour value Difference Complete
1 123 1 1 6 NULL 0
2 123 1 2 8 NULL 0
3 123 1 5 21 NULL 0
4 123 1 6 28 NULL 0
5 222 2 2 12 NULL 0
6 222 2 5 18 NULL 0
7 222 2 4 16 NULL 0
8 222 1 12 8 NULL 0
For each serial number there will be a day 1-365 and hour through 1-12, all I want to do is calculate the difference filed from the record before
So take ImportID 6, I need to get the record which is on the same day and the hour before (importID 7) then I need to update the Difference using the value field which is 18 -17 = 1.
N.B. There may be gaps in the sequence and if there is no previous record then the difference should stay as NULL. Once they have been calculated they need to be inserted into a new table only when the difference is now not null and it doesn't exist in the table already, on a successful insert they get marked as complete. Also a record before can be a previous day (day 1 hour 12) is the record before (day 2, hour 1)
Currently I am using a loop to select the null values, get the previous record, update the record, if its OK insert into other table, update the Completed field.
My issue is that this is working on a million records and it is taking a long while to Select the applicable records (completed = 0) into a temp table and loop through each.
Is there any quicker way to mass process these as an update statement? Or separate statements?
The result should be
ImportID SeiralNumber Day Hour value Difference Complete
1 123 1 1 6 NULL 0
2 123 1 2 8 2 1
3 123 1 5 21 NULL 0
4 123 1 6 28 7 1
5 222 2 1 12 4 1
6 222 2 5 18 2 1
7 222 2 4 16 NULL 0
8 222 1 12 8 NULL 0
Thanks in advance
I think this is basically it isn't it?
DECLARE #TABLE TABLE
(
ImportId INT,
SerialNumber INT,
Day INT,
Hour INT,
Value INT,
Difference INT,
Complete INT
)
INSERT INTO #TABLE VALUES
(1,123,1,1,6,NULL,0),
(2,123,1,2,8,NULL,0),
(3,123,1,5,21,NULL,0),
(4,123,1,6,28,NULL,0),
(5,222,2,1,12,NULL,0),
(6,222,2,5,18,NULL,0),
(7,222,2,4,16,NULL,0),
(8,222,1,12,8,NULL,0)
SELECT * FROM #Table
UPDATE T
SET T.Difference = T.Value - TT.Value,
Complete = 1
FROM
(
SELECT *
,ROW_NUMBER() OVER (PARTITION BY SerialNumber ORDER BY Day ASC, Hour ASC) AS RowCounter
FROM #TABLE
WHERE Complete = 0 --Ignore completed ones
)AS T
INNER JOIN
(
SELECT *
,ROW_NUMBER() OVER (PARTITION BY SerialNumber ORDER BY Day ASC, Hour ASC) AS RowCounter
FROM #TABLE
)AS TT
ON T.SerialNumber = TT.SerialNumber
WHERE
(
T.RowCounter = TT.RowCounter + 1
AND
T.Day = TT.Day
AND
T.Hour = TT.Hour + 1
)
OR
(
T.Day = TT.Day + 1
AND
T.Hour = 1
AND
TT.Hour = 12
)
SELECT * FROM #TABLE

Line-shift report, Line-day report

I'm generating a line-shift report:
In my application, I'm providing a dropdownlist for selecting shift and line and they will select a date from calender
I have 3 shifts
shift1 starts at 7am and ends at 3pm
shift2 starts at 3pm and ends at 11pm
shift3 starts at 11pm and ends at 3am
I have a table called datalogging where login information will be stored as shown below:
Name Shiftname ID operatorname Date plantname line Machine
Pradeepa Shift2(11-7) 3 Operator 3 2011-05-28 Plant 3 Line5 mc10
Ashwini Shift1(7-3) 1 Operator 1 2011-05-29 Plant 3 Line6 mc12
Deepika Shift2(11-7) 2 Operator 3 2011-05-29 Plant 5 Line9 mc18
Ashwini Shift1(7-3) 1 Operator 1 2011-05-24 Plant 1 Line1 mc1
Deepika Shift2(3-11) 2 Operator 2 2011-05-24 Plant 2 Line3 mc5
Ashwini Shift2(3-11) 1 Operator 2 2011-05-25 Plant 2 Line3 mc5
and so on..
I have a parameter table like temperature,pressure,ph,speed,co2 etc
Temperature table contains following data and this table will contains all the reading from 7am to till 3am
Temperature Time Date
27 13:13:54.000 2011-05-25
27.3 13:14:04.000 2011-05-25
27.6 13:14:14.000 2011-05-25
27.9 13:14:24.000 2011-05-25
28.2 13:14:34.000 2011-05-25
28.5 13:14:44.000 2011-05-25
27 16:13:29.000 2011-05-26
27 16:13:31.000 2011-05-26
and so on..
The user will select a line from dropdownlist and shift and he will select a date from th calender
If the user select shift2,line3 and date 25/05/2011 what are the readings are there between 3pm to 11pm should be displayed in my report
My report should look like:
Machine Shiftname Date Time Temperature
mc5 Shift2 25/05/2011 13:13:54.000 27
mc5 Shift2 25/05/2011 13:14:04.000 27.3
mc5 Shift2 25/05/2011 13:14:14.000 27.6
I'm also doing line-day report
where shiftname should change according to time for eg if time changes to 23:00:00 shiftname should change to shift3 in my report
if the user select particular shift and date for eg if the user selects shift1,line1 and date my report should contain all reading between 7am to 3pm
can any one help me on this.
You could get your report with following query
SELECT d.Machine
, CASE WHEN t.time BETWEEN '19:00:00.000' AND '23:59:59.999' THEN 'Shift1'
WHEN t.time BETWEEN '00:00:00.000' AND '02:59:59.999' THEN 'Shift1'
WHEN t.time BETWEEN '03:00:00.000' AND '10:59:59.999' THEN 'Shift2'
WHEN t.time BETWEEN '11:00:00.000' AND '18:59:59.999' THEN 'Shift3'
END
, t.Date
, t.Time
, t.Temperature
FROM Datalogging d
INNER JOIN Temperature t ON t.Date = d.Date
WHERE d.Shifname = 'Shift2(3-11)'
AND d.Line = 'Line3'
AND t.Date = '25/05/2011'
but if we can assume that each machine would have temperature readings each day, it is clear that there's a relationship missing between your Temperature and Datalogging table.

Categories

Resources