Get rows having consecutive Month range in SQL - sql-server

I need to extract consecutive dates of a particular installation and reject all installations that does not have consecutive dates.
for example
The following is my query:
SELECT
Installation_no
,RDNG_STTS_CD
,UPDTD_DT
,ROW_NUMBER() OVER (PARTITION BY Installation_no ORDER BY UPDTD_DT ASC) AS RowNum
FROM
mrdg_tbl_download_DailyBKP
WHERE
RDNG_STTS_CD = 'PL';
that resulted in the following data:
+-----------------+--------------+-------------------------+--------+
| Installation_no | RDNG_STTS_CD | UPDTD_DT | RowNum |
+-----------------+--------------+-------------------------+--------+
| 5000002099 | PL | 2018-05-14 11:47:01.050 | 1 |
| 5000002099 | PL | 2018-05-14 11:47:01.050 | 2 |
| 5000002101 | PL | 2018-06-19 14:39:33.633 | 1 |
| 5000002101 | PL | 2018-06-19 14:39:33.633 | 2 |
| 5000002101 | PL | 2018-07-19 16:07:23.723 | 3 |
| 5000002101 | PL | 2018-07-19 16:07:23.723 | 4 |
| 5000002110 | PL | 2018-01-04 15:49:08.017 | 1 |
| 5000002110 | PL | 2018-01-04 15:49:08.017 | 2 |
| 5000002187 | PL | 2018-01-23 14:51:59.160 | 1 |
| 5000002187 | PL | 2018-01-23 14:51:59.160 | 2 |
| 5000002187 | PL | 2018-03-25 12:39:43.343 | 3 |
| 5000002187 | PL | 2018-03-25 12:39:43.343 | 4 |
| 5000002187 | PL | 2018-04-27 16:31:20.420 | 5 |
| 5000002187 | PL | 2018-04-27 16:31:20.420 | 6 |
| 5000002187 | PL | 2018-05-29 17:54:20.520 | 7 |
| 5000002187 | PL | 2018-05-29 17:54:20.520 | 8 |
| 5000002187 | PL | 2018-06-28 17:10:12.613 | 9 |
| 5000002187 | PL | 2018-06-28 17:10:12.613 | 10 |
| 5000002438 | PL | 2018-01-31 16:03:38.137 | 1 |
| 5000002438 | PL | 2018-01-31 16:03:38.137 | 2 |
| 5000002438 | PL | 2018-03-04 15:19:41.340 | 3 |
| 5000002438 | PL | 2018-03-04 15:19:41.340 | 4 |
| 5000002438 | PL | 2018-04-04 16:45:01.040 | 5 |
| 5000002438 | PL | 2018-04-04 16:45:01.040 | 6 |
| 5000002438 | PL | 2018-05-07 15:58:54.553 | 7 |
| 5000002438 | PL | 2018-05-07 15:58:54.553 | 8 |
| 5000002438 | PL | 2018-06-07 14:26:45.647 | 9 |
| 5000002438 | PL | 2018-06-07 14:26:45.647 | 10 |
| 5000002438 | PL | 2018-07-10 15:53:54.753 | 11 |
| 5000002438 | PL | 2018-07-10 15:53:54.753 | 12 |
+-----------------+--------------+-------------------------+--------+
The above is a sample data. and i have around 200 000 records in each category (here category is 'PL')
I need a distinct installation having consecutive month range (month 1,2,3,4,5).
I have tried every example in stack overflow but could not get precise answer.

Related

SQL query to aggregate result from child table

I need to join 4 table and display records in my application
route1
-------------------------
| ID | MODE | SCH DATE |
| 1 | T | 1/12019 |
| 2 | T | 2/12019 |
| 3 | T | 2/12019 |
--------------------------
Stop2
----------------------------
| ID | routeID | LocationID |
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 4 |
| 5 | 2 | 5 |
| 6 | 3 | 6 |
-----------------------------
StopOrder2
----------------------------
| ID | StopID | Wight |
| 1 | 1 | 100 |
| 2 | 1 | 2 |
| 3 | 2 | 3 |
| 4 | 2 | 1 |
| 5 | 3 | 2 |
| 6 | 3 | 3 |
| 7 | 4 | 2 |
| 8 | 4 | 3 |
| 9 | 5 | 2 |
| 10 | 5 | 3 |
| 11 | 6 | 2 |
| 12 | 6 | 3 |
-----------------------------
Location
| LocationID | Name, City, Zip
| 1 | name1,city1 1111
| 2 | name2,city2 2222
| 3 | name3,city3 333
-----------------------------
I want final result with each route have how many records and how many orders and sum of all order wight
-----------------------------------------
| RouteID | MODE | SCH DATE |No Of Stop |LastLocatioID|OrderCount|
| 1 | T | 1/12019 | 3 | 3 | 6 |
| 2 | T | 2/12019 | 2 | 5 | 4 |
| 3 | T | 2/12019 | 1 | 6 | 2 |
How can I write the SQL query I need?
All you need is a simple group by:
SELECT
r.ID AS RouteID,
r.MODE,
r.[SCH DATE],
COUNT(s.ID) AS [No Of Stop],
MAX(s.LocationID) AS [LastLocationID],
COUNT(o.ID) AS OrderCount
FROM
#route1 r
INNER JOIN #Stop2 s
ON r.ID = s.routeID
INNER JOIN #StopOrder2 o
ON s.ID = o.StopID
GROUP BY
r.ID,
r.MODE,
r.[SCH DATE]
Output:

Sum, Group by and Null

I'm dipping my toes into SQL. I have the following table
+------+----+------+------+-------+
| Type | ID | QTY | Rate | Name |
+------+----+------+------+-------+
| B | 1 | 1000 | 21 | Jack |
| B | 2 | 2000 | 12 | Kevin |
| B | 1 | 3000 | 24 | Jack |
| B | 1 | 1000 | 23 | Jack |
| B | 3 | 200 | 13 | Mary |
| B | 2 | 3000 | 12 | Kevin |
| B | 4 | 4000 | 44 | Chris |
| B | 4 | 5000 | 43 | Chris |
| B | 3 | 1000 | 26 | Mary |
+------+----+------+------+-------+
I don't know how I would leverage Sum and Group by to achieve the following result.
+------+----+------+------+-------+------------+
| Type | ID | QTY | Rate | Name | Sum of QTY |
+------+----+------+------+-------+------------+
| B | 1 | 1000 | 21 | Jack | 5000 |
| B | 1 | 3000 | 24 | Jack | Null |
| B | 1 | 1000 | 23 | Jack | Null |
| B | 2 | 3000 | 12 | Kevin | 5000 |
| B | 2 | 3000 | 12 | Kevin | Null |
| B | 3 | 200 | 13 | Mary | 1200 |
| B | 3 | 1000 | 26 | Mary | Null |
| B | 4 | 4000 | 44 | Chris | 9000 |
| B | 4 | 5000 | 43 | Chris | Null |
+------+----+------+------+-------+------------+
Any help is appreciated!
You can use window function :
select t.*,
(case when row_number() over (partition by type, id order by name) = 1
then sum(qty) over (partition by type, id order by name)
end) as Sum_of_QTY
from table t;

Need to update "orderby" column

I have a table test
+----+--+------+--+--+----------+--+--------------+
| ID | | Name | | | orderby | | processgroup |
+----+--+------+--+--+----------+--+--------------+
| 1 | | ABC | | | 10 | | 1 |
| 10 | | DEF | | | 12 | | 1 |
| 15 | | LMN | | | 1 | | 1 |
| 44 | | JKL | | | 4 | | 1 |
| 42 | | XYZ | | | 3 | | 2 |
+----+--+------+--+--+----------+--+--------------+
I want to update the orderby column in the sequence, I am expecting output like
+----+--+------+--+--+----------+--+--------------+
| ID | | Name | | | orderby | | processgroup |
+----+--+------+--+--+----------+--+--------------+
| 1 | | ABC | | | 1 | | 1 |
| 10 | | DEF | | | 2 | | 1 |
| 15 | | LMN | | | 3 | | 1 |
| 44 | | JKL | | | 4 | | 1 |
| 42 | | XYZ | | | 5 | | 1 |
+----+--+------+--+--+----------+--+--------------+
Logic behind this is when we have procesgroup as 1, orderby column should update as 1,2,3,4 and when procesgroup is 2 then update orderby as 5.
This might help you
;WITH CTE AS (
SELECT ROW_NUMBER() OVER (ORDER BY processgroup, ID ) AS SNO, ID FROM TABLE1
)
UPDATE TABLE1 SET TABLE1.orderby= CTE.SNO FROM CTE WHERE TABLE1.ID = CTE.ID

Row number by 3 distincts fields in SQL Server

I have this table:
| RecordLocator | DepartureStation | ArrivalStation | JourneyNumber | SegmentNumber | LegNumber | FlightNumber |
|---------------|------------------|----------------|---------------|---------------|-----------|--------------|
| DADABC | MAO | GRU | 2 | 1 | 1 | 1421 |
| CEDLDA | MAO | STM | 1 | 2 | 1 | 1643 |
| CEDLDA | GRU | MAO | 1 | 1 | 1 | 1640 |
| DADABC | GRU | FLN | 1 | 1 | 1 | 1848 |
| CEDLDA | BEL | SLZ | 1 | 2 | 3 | 1643 |
| DADABC | GIG | FOR | 1 | 2 | 3 | 1154 |
| CEDLDA | SLZ | FOR | 1 | 2 | 4 | 1680 |
| CEDLDA | FOR | REC | 1 | 2 | 5 | 1680 |
| DADABC | FOR | MAO | 1 | 2 | 4 | 1982 |
| CEDLDA | REC | SSA | 1 | 2 | 6 | 1680 |
| CEDLDA | STM | BEL | 1 | 2 | 2 | 1643 |
| DADABC | POA | GIG | 1 | 2 | 2 | 1201 |
| CEDLDA | SSA | GRU | 1 | 3 | 1 | 1817 |
| DADABC | FLN | POA | 1 | 2 | 1 | 1201 |
I want add a new column row number based on JourneyNumber, SegmentNumber and LegNumber, order by RecordLocator, for obtain this result:
| RecordLocator | DepartureStation | ArrivalStation | JourneyNumber | SegmentNumber | LegNumber | FlightNumber | rowNum |
|---------------|------------------|----------------|---------------|---------------|-----------|--------------|--------|
| CEDLDA | GRU | MAO | 1 | 1 | 1 | 1640 | 1 |
| CEDLDA | MAO | STM | 1 | 2 | 1 | 1643 | 2 |
| CEDLDA | STM | BEL | 1 | 2 | 2 | 1643 | 3 |
| CEDLDA | BEL | SLZ | 1 | 2 | 3 | 1643 | 4 |
| CEDLDA | SLZ | FOR | 1 | 2 | 4 | 1680 | 5 |
| CEDLDA | FOR | REC | 1 | 2 | 5 | 1680 | 6 |
| CEDLDA | REC | SSA | 1 | 2 | 6 | 1680 | 7 |
| CEDLDA | SSA | GRU | 1 | 3 | 1 | 1817 | 8 |
| DADABC | GRU | FLN | 1 | 1 | 1 | 1848 | 1 |
| DADABC | FLN | POA | 1 | 2 | 1 | 1201 | 2 |
| DADABC | POA | GIG | 1 | 2 | 2 | 1201 | 3 |
| DADABC | GIG | FOR | 1 | 2 | 3 | 1154 | 4 |
| DADABC | FOR | MAO | 1 | 2 | 4 | 1982 | 5 |
| DADABC | MAO | GRU | 2 | 1 | 1 | 1421 | 6 |
I tried this query:
SELECT
RecordLocator,
DepartureStation, ArrivalStation,
JourneyNumber, SegmentNumber,
LegNumber, FlightNumber,
(SELECT ((P.JourneyNumber + P.SegmentNumber + P.LegNumber))
FROM PAX P2
WHERE P2.RecordLocator = P.RecordLocator
AND P2.DepartureStation = P.DepartureStation
AND P2.ArrivalStation = P.ArrivalStation
AND P2.JourneyNumber = P.JourneyNumber
AND P2.SegmentNumber = P.SegmentNumber
AND P2.LegNumber = P.LegNumber
AND P2.FlightNumber = P.FlightNumber) AS rowNum
FROM
PAX P
I'm trying sum the columns JourneyNumber, SegmentNumber and LegNumber but does not work, i belive best way to do, is based on Recordlocator define a "weight" for the columns JourneyNumber > SegmentNumber > LegNumber, but i don't know how implement it.
In C# I know how to do it, using align for:
// First `for` - Journey
for(int i = 0; i < Journey.Count(); i++)
{
// Second `for` - Segment
for(int j = 0; j < Segment.Count(); j++)
{
// Third `for` - Leg
for(int k = 0; k < Leg.Count(); k++)
{
result = i + j + k;
}
}
}
Basically, breaking down your question into its parts, you want to re-start numbering for each RecordLocator, then you order it by the 3 fields you wanted in ascending order.
Overall, that's the idea of the ROW_NUMBER() which allows for ordering your records with a partition set for RecordLocator to re-start the numbering as needed. So, something like this should do it:
ROW_NUMBER() OVER(PARTITION BY RecordLocator ORDER BY JourneyNumber, SegmentNumber, LegNumber)
And your final SQL, therefore, becoming:
SELECT RecordLocator
, DepartureStation
, ArrivalStation
, JourneyNumber
, SegmentNumber
, LegNumber
, FlightNumber
, ROW_NUMBER() OVER(PARTITION BY RecordLocator ORDER BY JourneyNumber, SegmentNumber, LegNumber) AS rowNum
FROM PAX P
Hope this does the trick!

Values differences between days

I have a SQL Server 2005 table titled "Journeys" as follows:
+---------------+
| Journeys |
+---------------+
| JourneyID |
| PlateNumber |
| DepartureDate |
| DepartureKM |
| ArrivalDate |
| ArrivalKM |
+---------------+
The table contains the following sample data:
+------------+--------------+----------------+--------------+--------------+-----------+
| JOURNEYID | PLATENUMBER | DEPARTUREDATE | DEPARTUREKM | ARRIVALDATE | ARRIVALKM |
+------------+--------------+----------------+--------------+--------------+-----------+
| 1 | ABC-123 | 01-01-2015 | 10000 | 01-02-2015 | 10200 |
| 2 | ABC-123 | 01-02-2015 | 10210 | 01-03-2015 | 10500 |
| 3 | ABC-123 | 01-03-2015 | 10500 | 01-04-2015 | 10650 |
| 4 | ABC-123 | 01-04-2015 | 10607 | 01-05-2015 | 10900 |
| 5 | XYZ-999 | 01-15-2015 | 30200 | 01-16-2015 | 30400 |
| 6 | XYZ-999 | 01-16-2015 | 30405 | 01-17-2015 | 30600 |
| 7 | XYZ-999 | 01-17-2015 | 30600 | 01-18-2015 | 30750 |
| 8 | XYZ-999 | 01-18-2015 | 30752 | 01-19-2015 | 30920 |
+------------+--------------+----------------+--------------+--------------+-----------+
I want to generate a query that returns a the following results with an extra column named 'KMDifference' which is the difference between 'ArrivalKM' from last day and 'DepartureKM' from today.
Desired results:
+-------------+---------------+-------------+-------------+-----------+--------------+
| PlateNumber | DepartureDate | DepartureKM | ArrivalDate | ArrivalKM | KMDifference |
+-------------+---------------+-------------+-------------+-----------+--------------+
| ABC-123 | 01-01-2015 | 10000 | 01-02-2015 | 10200 | 0 |
| ABC-123 | 01-02-2015 | 10210 | 01-03-2015 | 10500 | 10 |
| ABC-123 | 01-03-2015 | 10500 | 01-04-2015 | 10650 | 0 |
| ABC-123 | 01-04-2015 | 10607 | 01-05-2015 | 10900 | 7 |
| XYZ-999 | 01-15-2015 | 30200 | 01-16-2015 | 30400 | 0 |
| XYZ-999 | 01-16-2015 | 30405 | 01-17-2015 | 30600 | 5 |
| XYZ-999 | 01-17-2015 | 30600 | 01-18-2015 | 30750 | 0 |
| XYZ-999 | 01-18-2015 | 30752 | 01-19-2015 | 30920 | 2 |
+-------------+---------------+-------------+-------------+-----------+--------------+
See this SQL Fiddle here: http://sqlfiddle.com/#!3/28abd
You can use the following CTE based query in order to simulate LAG function available from SQL Server 2012 onwards:
;WITH Journeys_rn AS (
SELECT JourneyID, PlateNumber, DepartureDate, DepartureKM, ArrivalDate, ArrivalKM,
ROW_NUMBER() OVER(PARTITION BY PlateNumber ORDER BY DepartureDate) AS rn
FROM Journeys
)
SELECT j1.PlateNumber, j1.DepartureDate, j1.DepartureKM,
j1.ArrivalDate, j1.ArrivalKM,
j1.DepartureKM - ISNULL(j2.ArrivalKM, j1.DepartureKM) AS KMDifference
FROM Journeys_rn AS j1
LEFT JOIN Journeys_rn AS j2 ON j1.rn = j2.rn+1 AND j1.PlateNumber = j2.PlateNumber
j2.ArrivalKM in the above query is the value from previous record. ISNULL is needed so that a 0 value is calculated for the first record of each group.
SQL Fiddle Demo
P.S. The sample data in the OP do not match with the sample data of the SQL Fiddle source also provided in the OP. So had to fix it in order to get the desired reult set.

Resources