Get the 3rd largest time value in SQL Server 2018 - sql

I want to get the 1st, 2nd, 3rd,...largest value of Time in SQL Server 2018's table.
In my code when I get the 3rd largest, if my month condition is 5, it returns correct value. But if my month condition is 4, it returns the max time value not my expected time value ( 3rd ). I don't know why.
My query:
SELECT MAX([Time1].[Time]) FROM [dbo].[index4_MonthChart] as [Time1]
WHERE
Month([Time]) = '4'
AND [Time1].[Time] < ( SELECT MAX([Time2].[Time]) FROM [dbo].[index4_MonthChart] as [Time2]
WHERE
[Time2].[Time] < ( SELECT MAX([Time3].[Time]) FROM [dbo].[index4_MonthChart] as [Time3]))
All my value in table:
When month(time) condition is 5, it returns:
But when month(time) is 4, it always returns the max time value and it is wrong ( The correct time value have to be 2023-04-28 ) :

Very simple. You need to add a where clause in your sub-selects to restrict those to Month= 4 as well. Since there are at least two times greater than 30.04 (IE all the times from May), your current query returns the maximum time for April. This doesn't happen for May, because your data has no values later than May.

Related

Identifying if a column is in descending order

I am using Microsoft SQL Server 2005 Management Studio. I am a bit new so I hope I am not breaking any rules. My data is 15 columns and almost a million rows, however I am just giving you a sample to get assistance on one area where I am stuck.
In the above example as you can see the column 'lastlevel' values are decreasing. Also you can see that data in the 'Last_read' column date range is from today to 14 days prior (it was ran yesterday hence April 27, also pls. disregard that for 1st customer date 2021/04/14 is missing, it is an anomaly).
Column 'Shipto' provides the customer number and each customer has max 14 rows of data.
Please disregard column 'current_reading' and rn
If look at 'lastlevel' again you will notice that the values are going down consistently, however on April 18th, it goes from 0.73 to 0.74, showing an increase of 0.01.
What I want to do is that whenever there is an increase at all, I want that whole customer's all 14 rows be removed from the output i.e. I only want to see customers that have the prefect descending data and no increases.
Can you help?
WITH
deltas AS
(
-- For each [Shipto]; deduct the preceding row's value and record it as the [delta]
-- Note, each [Shipto]'s first row's delta with therefor be NULL
SELECT
*,
lastlevel - LAG(lastlevel) OVER (PARTITION BY Shipto ORDER BY Last_Read, lastlevel DESC) AS delta
FROM
yourTable
),
max_deltas AS
(
-- Get the maximum of the deltas per [Shipto]
SELECT
*,
MAX(delta) OVER (PARTITION BY Shipto) AS max_delta
FROM
deltas
)
-- Return only rows where the delta never exceeds 0 (thus, never ascending over any timestep)
SELECT
*
FROM
max_deltas
WHERE
max_delta <= 0
I've ordered by Last_Read, lastlevel DESC such that if two readings are on the same date, it is assumed that the highest value should be considered to have happened first.

Sql count and and/or condition in single statement

I am trying to build where clause condition on table having columns “Id”, itemNumber” which can be either 1 or 2 for any row and “date”.
My goal is to write where clause such that i only get “Id’s” where “itemNumber” is 2, and then if count is greater than some value it should filter whole rows to date between today and today+1, otherwise today and today+2.
I tried,
Select Id
from table
where itemNumber=2 And ((count(itemNumber)>2 and date between ‘today’ and ‘today+1’) OR (count(itemNumber)<=2 and date between ‘today’ and ‘today+2’))
I got error saying you need to have sql “having”. Am i doing it wrong?
Try it like this:
SELECT id
FROM t
WHERE itemNumber = 2
GROUP BY id
HAVING (COUNT(itemNumber) > 2 AND date BETWEEN 'today' and 'today+1'))
OR (COUNT(itemNumber) <= 2 AND date BETWEEN 'today' and 'today+2'))
Think of HAVING as a WHERE clause after you have grouped your data, which you have to do if you want to count something by group (or id).

Oracle - Count the same value used on consecutive days

Date jm Text
-------- ---- ----
6/3/2015 ne Good
6/4/2015 ne Good
6/5/2015 ne Same
6/8/2015 ne Same
I want to count how often the "same" value occurs in a set of consecutive days.
I dont want to count the value for the whole database. Now on the current date it is 2 (above example).
It is very important for me that "Same" never occurs...
The query has to ignore the weekend (6 and 7 june).
Date jm Text
-------- ---- ----
6/3/2015 ne Same
6/4/2015 ne Same
6/5/2015 ne Good
6/8/2015 ne Good
In this example the count is zero
Okay, I'm starting to get the picture, although at first I thought you wanted to count by jm, and now it seems you want to count by Text = 'Same'. Anyway, that's what this query should do. It gets the row for the current date. Is connects all previous rows and counts them. Also, it shows whether the current text (and that of the connected rows).
So the query will return one row (if there is one for today), which will show the date, jm and Text of the current date, the number of consecutive days for which the Text has been the same (just in case you want to know how many days it is 'Good'), and the number of days (either 0 or the same as the other count) for which the Text has been 'Same'.
I hope this query is right, or at least it gives you an idea of how to solve the problem using CONNECT BY. I should mention I based the 'Friday-detection' on this question.
Also, I don't have Oracle at hand, so please forgive me for any minor syntax errors.
WITH
VW_SAMESTATUSES AS
( SELECT t.*
FROM YourTable t
START WITH -- Start with the row for today
t.Date = trunc(sysdate)
CONNECT BY -- Connect to previous row that have a lower date.
-- Note that PRIOR refers to the prior record, which is
-- actually the NEXT day. :)
t.Date = PRIOR t.Date +
CASE MOD(TO_CHAR(t.Date, 'J'), 7) + 1
WHEN 5 THEN 3 -- Friday, so add 3
ELSE 1 -- Other days, so add one
END
-- And the Text also has to match to the one of the next day.
AND t.Text = PRIOR t.Text)
SELECT s.Date,
s.jm,
MAX(Text) AS CurrentText, -- Not really MAX, they are actually all the same
COUNT(*) AS ConsecutiveDays,
COUNT(CASE WHEN Text = 'Same' THEN 1 END) as SameCount
FROM VW_SAMESTATUSES s
GROUP BY s.Date,
s.jm
This recursive query (available from Oracle version 11g) might be useful:
with s(tcode, tdate) as (
select tcode, tdate from test where tdate = date '2015-06-08'
union all
select t.tcode, t.tdate from test t, s
where s.tcode = t.tcode
and t.tdate = s.tdate - decode(s.tdate-trunc(s.tdate, 'iw'), 0, 3, 1) )
select count(1) cnt from s
SQLFiddle
I prepared sample data according to your original question, without further edits, you can see them in attached SQLFiddle. Additional conditions for column 'Text'
are very simple, just add something like ... and Text ='Same' in where clauses.
In current version query counts number of previous days starting from given date (change it in line 2) where dates are consecutive (excluding weekend days) and values in column tcode is the same for all days.
Part: decode(s.tdate-trunc(s.tdate, 'iw'), 0, 3, 1) is for substracting days depending if it's Monday or other day, and should work independently from NLS settings.

Comparing data between reporting periods MS Access

I have a big table that contains records for each reporting period in my project.
The period is indentified by an integer 1, 2, 3, 4, 5, 6, 7.
Each period contains about 7000 rows of tasks each identified a unique ID. These tasks all have a percent complete column which is an integer.
I want to add a comparison column.
so it would look up the unique id in the previous period then return the difference in percent complete.
eg
for
Period: 8 Item Unique ID: 42w3wer324wer32 Percent complete: 50
it would find:
Period: 7 Item Unique ID: 42w3wer324wer32 Percent complete: 40
the fill in the field with: 10.
If it could not find the Item Unique ID in the previous period then it would default to 0.
thanks
As I understand your description, you could pull the data for period 8 like this:
SELECT item_id, pct_complete
FROM YourTable
WHERE rpt_period = 8;
And the previous period would be the same query except substituting 7 as the period.
So take the period 8 query and left join it to a subquery for period 7.
SELECT
y.item_id,
(y.pct_complete - Nz(sub.pct_complete, 0)) AS change_in_pct_complete
FROM YourTable AS y
LEFT JOIN
(
SELECT item_id, pct_complete
FROM YourTable
WHERE rpt_period = 7
) AS sub
ON y.item_id = sub.item_id
WHERE rpt_period = 8;
That Nz() expression will substitute 0 for Null when no period 7 match exists for a period 8 item_id.
If you need a query which will not be running from within an Access session, the Nz() function will not be available. In that case, you can use an IIf() expression ... it's not as concise, but it will get the job done.
IIf(sub.pct_complete Is Null, 0, sub.pct_complete)

Get data between record in table

I have data like this:
For example, today is on April 2012. Referring to data above, I want to get the data with M_PER = 03-2012 because this month is in the range 03-2012 TO 06-2012.
--EditedIn this case, I wanna get a rate for used currency code. Because today is still in April, and I want to know rate US Dollar (USD) to Indonesia Rupiah (IDR) I must get the data with M_PER = 03-2012 and CRR_CURRENCY_CODE = USD.
The question is what query can retrieve data like that?
Since you seem to be using quarterly values, I would use the TRUNC function with the 'Q' format model. This truncates a date to 1/1/YYYY, 1/4/YYYY, 1/7/YYYY and 1/10/YYYY, i.e. the first day of the quarter.
To fit your model which is the month at the end of the quarter, you would then have to add two months. This assumes that the MONTH_PERIOD column is a SQL date and not some other data type.
Included below is an example, using SYSDATE as the input date.
select *
from your_table
where add_months(trunc(sysdate, 'Q'),2) = month_period;
I use the rownum and order by to get the value.
SELECT * FROM tables WHERE m_per > '04-2012' AND ROWNUM = 1 ORDER BY month_period ASC