I am trying to compute TO_DATE
column for a group of BINGID
, INDUSID
, COMP1
.
When IsRowActive = 1
then TO_DATE
= "9999-12-31" , which is being returned correctly.
But when IsRowActive = 0
, then we have to calculate To_Date
which should be 1 sec less than next FROMDT
Data :
DECLARE @MYTABLE TABLE
(
BINGID INT,
INDUSID INT,
DTSEARCH DATETIME2,
COMP1 VARCHAR (100),
LISTPRICE NUMERIC(10,2),
FROMDT DATETIME2,
IsRowActive INT
)
INSERT @MYTABLE
SELECT 1002285, 1002, '2016-03-03 04:10:58.0000000', '0026PU009163-031', '77.7600', '2015-12-19 12:51:49.0000000',0 UNION ALL
SELECT 1002285, 1002, '2016-05-27 12:14:53.0000000', '0026PU009163-031', '85.2200', '2016-05-27 12:14:53.0000000',0 UNION ALL
SELECT 1002285, 1002, '2016-07-20 06:44:37.0000000', '0026PU009163-031', '90.3900', '2016-07-20 06:44:37.0000000',0 UNION ALL
SELECT 1002285, 1002, '2016-11-09 13:37:13.0000000', '0026PU009163-031', '131.4500', '2016-10-18 13:49:10.0000000',1 UNION ALL
SELECT 1002285, 1002, '2015-12-19 12:51:41.0000000', '10122374', 65.1400, '2015-12-19 12:51:41.0000000', 0 UNION ALL
SELECT 1002285, 1002, '2016-03-03 04:11:01.0000000', '10122374', 117.2100, '2016-03-03 04:11:01.0000000', 0 UNION ALL
SELECT 1002285, 1002, '2016-05-27 12:14:45.0000000', '10122374', 53.5500, '2016-05-27 12:14:45.0000000', 0 UNION ALL
SELECT 1002285, 1002, '2016-07-20 06:44:29.0000000', '10122374', 48.5000, '2016-07-20 06:44:29.0000000', 0 UNION ALL
SELECT 1002285, 1002, '2016-10-18 13:49:00.0000000', '10122374', 75.6800, '2016-10-18 13:49:00.0000000', 0 UNION ALL
SELECT 1002285, 1002, '2016-11-09 13:37:02.0000000', '10122374', 68.2400, '2016-11-09 13:37:02.0000000', 1 UNION ALL
SELECT 1000001, 1002, '2016-03-03 02:22:09.0000000', '161GDB1577', 37.1700, '2015-12-18 06:45:05.0000000',0 UNION ALL
SELECT 1000001, 1002, '2016-03-03 02:22:18.0000000', '0392347402', 41.9100, '2015-12-18 06:45:14.0000000',0 UNION ALL
SELECT 1000001, 1002, '2016-05-26 14:54:28.0000000', '161GDB1577', 46.7100, '2016-05-26 14:54:28.0000000',0 UNION ALL
SELECT 1000001, 1002, '2016-05-26 14:54:42.0000000', '0392347402', 54.7100, '2016-05-26 14:54:42.0000000',0 UNION ALL
SELECT 1000001, 1002, '2016-07-15 06:34:33.0000000', '161GDB1577', 52.4800, '2016-07-15 06:34:33.0000000',0 UNION ALL
SELECT 1000001, 1002, '2016-07-15 06:34:45.0000000', '0392347402', 81.7100, '2016-07-15 06:34:45.0000000',0 UNION ALL
SELECT 1000001, 1002, '2016-10-17 11:26:45.0000000', '161GDB1577', 61.6400, '2016-10-17 11:26:45.0000000',0 UNION ALL
SELECT 1000001, 1002, '2016-11-09 02:21:17.0000000', '0392347402', 81.9200, '2016-10-17 11:26:58.0000000',1 UNION ALL
SELECT 1000001, 1002, '2016-11-09 02:21:05.0000000', '161GDB1577', 78.3500, '2016-11-09 02:21:05.0000000',1 UNION ALL
SELECT 1000005, 1002, '2018-11-09 02:21:05.0000000', '556556GHB', 78.3500, '2018-11-09 02:21:05.0000000',1
Query I tried - unfortunately it is returning the wrong data :
SELECT
BINGID, INDUSID, DTSEARCH,
COMP1, LISTPRICE, FROMDT,
CASE
WHEN IsRowActive = 1
THEN '9999-12-31'
ELSE TO_DATE
END AS TO_DATE,
IsRowActive
FROM
@MYTABLE mt
OUTER APPLY
(SELECT
MAX(DATEADD(second, -1, FROMDT)) TO_DATE
FROM
@MYTABLE mt2
WHERE
mt2.BINGID = mt.BINGID
AND mt2.INDUSID = mt.INDUSID
AND mt2.FROMDT > mt.FROMDT) oa
WHERE
mt.INDUSID = '1002'
Expected output
BINGID INDUSID DTSEARCH COMP1 LISTPRICE FROMDT NEW_TO_DATE IsRowCurrent
1000001 1002 2016-03-03 02:22:09.0000000 161GDB1577 37.1700 2015-12-18 06:45:05.0000000 2016-05-26 14:54:27.0000000 0
1000001 1002 2016-03-03 02:22:18.0000000 0392347402 41.9100 2015-12-18 06:45:14.0000000 2016-05-26 14:54:41.0000000 0
1000001 1002 2016-05-26 14:54:28.0000000 161GDB1577 46.7100 2016-05-26 14:54:28.0000000 2016-07-15 06:34:32.0000000 0
1000001 1002 2016-05-26 14:54:42.0000000 0392347402 54.7100 2016-05-26 14:54:42.0000000 2016-07-15 06:34:44.0000000 0
1000001 1002 2016-07-15 06:34:33.0000000 161GDB1577 52.4800 2016-07-15 06:34:33.0000000 2016-10-17 11:26:44.0000000 0
1000001 1002 2016-07-15 06:34:45.0000000 0392347402 81.7100 2016-07-15 06:34:45.0000000 2016-10-17 11:26:57.0000000 0
1000001 1002 2016-10-17 11:26:45.0000000 161GDB1577 61.6400 2016-10-17 11:26:45.0000000 2016-11-09 02:21:04.0000000 0
1000001 1002 2016-11-09 02:21:17.0000000 0392347402 81.9200 2016-10-17 11:26:58.0000000 9999-12-31 00:00:00.0000000 1
1000001 1002 2016-11-09 02:21:05.0000000 161GDB1577 78.3500 2016-11-09 02:21:05.0000000 9999-12-31 00:00:00.0000000 1
1000005 1002 2018-11-09 02:21:05.0000000 556556GHB 78.3500 2018-11-09 02:21:05.0000000 9999-12-31 00:00:00.0000000 1
1002285, 1002, '2016-03-03 04:10:58.0000000', '0026PU009163-031', '77.7600', 2015-12-19 12:51:49.0000000' 2016-05-27 12:14:52.0000000' 0
1002285, 1002, '2016-05-27 12:14:53.0000000', '0026PU009163-031', '85.2200', 2016-05-27 12:14:53.0000000' 2016-07-20 06:44:36.0000000' 0
1002285, 1002, '2016-07-20 06:44:37.0000000', '0026PU009163-031', '90.3900', 2016-07-20 06:44:37.0000000' 2016-10-18 13:49:09.0000000' 0
1002285, 1002, '2016-11-09 13:37:13.0000000', '0026PU009163-031', '131.4500', 2016-10-18 13:49:10.0000000' 9999-12-31 00:00:00.0000000 1
1002285, 1002, '2015-12-19 12:51:41.0000000', '10122374', 65.1400, '2015-12-19 12:51:41.0000000', 2016-03-03 04:11:00.0000000', 0
1002285, 1002, '2016-03-03 04:11:01.0000000', '10122374', 117.2100, '2016-03-03 04:11:01.0000000', 2016-05-27 12:14:44.0000000', 0
1002285, 1002, '2016-05-27 12:14:45.0000000', '10122374', 53.5500, '2016-05-27 12:14:45.0000000', 2016-07-20 06:44:28.0000000', 0
1002285, 1002, '2016-07-20 06:44:29.0000000', '10122374', 48.5000, '2016-07-20 06:44:29.0000000', 2016-10-18 13:48:59.0000000', 0
1002285, 1002, '2016-10-18 13:49:00.0000000', '10122374', 75.6800, '2016-10-18 13:49:00.0000000', 2016-11-09 13:37:01.0000000', 0
1002285, 1002, '2016-11-09 13:37:02.0000000', '10122374', 68.2400, '2016-11-09 13:37:02.0000000', 9999-12-31 00:00:00.0000000 1
Thanks.
MySQL DATE() Function The DATE() function extracts the date part from a datetime expression.
The DATEDIFF() function returns the difference between two dates.
I really like @Chanukya's answer. But as you are using 2008 you will cannot use the LEAD function. Instead, you can use a self-join:
-- SQL Server 2008.
SELECT
c.*,
CASE c.IsRowActive
WHEN 1 THEN '9999-12-31'
ELSE DATEADD(SECOND, -1, MIN(p.FROMDT))
END AS TO_DATE
FROM
@MYTABLE AS c
LEFT OUTER JOIN @MYTABLE AS p ON p.BINGID = c.BINGID
AND p.INDUSID = c.INDUSID
AND p.FROMDT > c.FROMDT
GROUP BY
c.BINGID,
c.INDUSID,
c.DTSEARCH,
c.COMP1,
c.LISTPRICE,
c.FROMDT,
c.IsRowActive
ORDER BY
c.FROMDT
;
The logic is similar to your outer apply, but it should perform better. This is because there is no correlation.
The sample data presented a small challenge. Because there are two records with a FROMDT
of 2016-07-20 06:44:37.0000000
you could argue my results are wrong.
Try this Simple and readable solution, Use CTE
and Self Join
with cte as
(
SELECT
ROW_NUMBER() over (order by BINGID,INDUSID,DTSEARCH,COMP1,LISTPRICE,FROMDT)
as rowno, -- It is good if you have identity column here
BINGID,
INDUSID,
DTSEARCH,
COMP1,
LISTPRICE,
FROMDT,
IsRowActive
FROM @MYTABLE mt
)
select c1.*,
CASE WHEN c1.IsRowActive = 1 THEN '9999-12-31' ELSE DATEADD(second, -1, c2.FROMDT) END
AS TO_DATE
from cte c1 left join cte c2
on c1.rowno+1 = c2.rowno
DECLARE @MYTABLE TABLE
(
BINGID int,
INDUSID int,
DTSEARCH datetime2,
COMP1 varchar(100),
LISTPRICE numeric(15,5),
FROMDT datetime2,
IsRowActive int
)
insert @MYTABLE
SELECT 1002285 ,1002 ,'2016-03-03 04:10:58.0000000', '0026PU009163-031', 77.7600 ,'2015-12-19 12:51:49.0000000', 0 UNION ALL
SELECT 1002285 ,1002 ,'2016-05-27 12:14:53.0000000', '0026PU009163-031', 85.2200 ,'2016-05-27 12:14:53.0000000', 0 UNION ALL
SELECT 1002285 ,1002 ,'2016-07-20 06:44:37.0000000', '0026PU009163-031', 90.3900 ,'2016-07-20 06:44:37.0000000', 0 UNION ALL
SELECT 1002285 ,1002 ,'2016-11-09 13:37:13.0000000', '0026PU009163-031', 131.4500,'2016-07-20 06:44:37.0000000', 1
select BINGID,DTSEARCH,COMP1,LISTPRICE,FROMDT,CASE WHEN IsRowActive = 0 THEN lead(DATEADD(SS,-1,FROMDT)) OVER (ORDER BY FROMDT) ELSE '9999-12-31' END AS expected_date
FROM @MYTABLE mt
output
BINGID DTSEARCH COMP1 LISTPRICE FROMDT expected_date
1002285 2016-03-03 04:10:58.0000000 0026PU009163-031 77.76000 2015-12-19 12:51:49.0000000 2016-05-27 12:14:52.0000000
1002285 2016-05-27 12:14:53.0000000 0026PU009163-031 85.22000 2016-05-27 12:14:53.0000000 2016-07-20 06:44:36.0000000
1002285 2016-07-20 06:44:37.0000000 0026PU009163-031 90.39000 2016-07-20 06:44:37.0000000 2016-07-20 06:44:36.0000000
1002285 2016-11-09 13:37:13.0000000 0026PU009163-031 131.45000 2016-07-20 06:44:37.0000000 9999-12-31 00:00:00.0000000
Instead of MAX
use TOP(1)
with appropriate ORDER BY
in the OUTER APPLY
.
Also, you said that you want to group by BINGID, INDUSID, COMP1
, so use all of these columns in the WHERE
clause in the OUTER APPLY
. Why did you omit COMP1
in your query?
Sample data
DECLARE @MYTABLE TABLE
(
BINGID INT,
INDUSID INT,
DTSEARCH DATETIME2,
COMP1 VARCHAR (100),
LISTPRICE NUMERIC(10,2),
FROMDT DATETIME2,
IsRowActive INT
)
INSERT INTO @MYTABLE
SELECT 1002285, 1002, '2016-03-03 04:10:58', '0026PU009163-031', 77.7600, '2015-12-19 12:51:49', 0 UNION ALL
SELECT 1002285, 1002, '2016-05-27 12:14:53', '0026PU009163-031', 85.2200, '2016-05-27 12:14:53', 0 UNION ALL
SELECT 1002285, 1002, '2016-07-20 06:44:37', '0026PU009163-031', 90.3900, '2016-07-20 06:44:37', 0 UNION ALL
SELECT 1002285, 1002, '2016-11-09 13:37:13', '0026PU009163-031', 131.4500, '2016-10-18 13:49:10', 1 UNION ALL
SELECT 1002285, 1002, '2015-12-19 12:51:41', '10122374', 65.1400, '2015-12-19 12:51:41', 0 UNION ALL
SELECT 1002285, 1002, '2016-03-03 04:11:01', '10122374', 117.2100, '2016-03-03 04:11:01', 0 UNION ALL
SELECT 1002285, 1002, '2016-05-27 12:14:45', '10122374', 53.5500, '2016-05-27 12:14:45', 0 UNION ALL
SELECT 1002285, 1002, '2016-07-20 06:44:29', '10122374', 48.5000, '2016-07-20 06:44:29', 0 UNION ALL
SELECT 1002285, 1002, '2016-10-18 13:49:00', '10122374', 75.6800, '2016-10-18 13:49:00', 0 UNION ALL
SELECT 1002285, 1002, '2016-11-09 13:37:02', '10122374', 68.2400, '2016-11-09 13:37:02', 1 UNION ALL
SELECT 1000001, 1002, '2016-03-03 02:22:09', '161GDB1577', 37.1700, '2015-12-18 06:45:05', 0 UNION ALL
SELECT 1000001, 1002, '2016-03-03 02:22:18', '0392347402', 41.9100, '2015-12-18 06:45:14', 0 UNION ALL
SELECT 1000001, 1002, '2016-05-26 14:54:28', '161GDB1577', 46.7100, '2016-05-26 14:54:28', 0 UNION ALL
SELECT 1000001, 1002, '2016-05-26 14:54:42', '0392347402', 54.7100, '2016-05-26 14:54:42', 0 UNION ALL
SELECT 1000001, 1002, '2016-07-15 06:34:33', '161GDB1577', 52.4800, '2016-07-15 06:34:33', 0 UNION ALL
SELECT 1000001, 1002, '2016-07-15 06:34:45', '0392347402', 81.7100, '2016-07-15 06:34:45', 0 UNION ALL
SELECT 1000001, 1002, '2016-10-17 11:26:45', '161GDB1577', 61.6400, '2016-10-17 11:26:45', 0 UNION ALL
SELECT 1000001, 1002, '2016-11-09 02:21:17', '0392347402', 81.9200, '2016-10-17 11:26:58', 1 UNION ALL
SELECT 1000001, 1002, '2016-11-09 02:21:05', '161GDB1577', 78.3500, '2016-11-09 02:21:05', 1 UNION ALL
SELECT 1000005, 1002, '2018-11-09 02:21:05', '556556GHB', 78.3500, '2018-11-09 02:21:05', 1
Query
SELECT
BINGID,
INDUSID,
DTSEARCH,
COMP1,
LISTPRICE,
FROMDT,
CASE WHEN IsRowActive = 1 THEN '9999-12-31' ELSE oa.TO_DATE END AS TO_DATE,
IsRowActive
FROM
@MYTABLE AS mt
OUTER APPLY
(
SELECT TOP(1) DATEADD(second, -1, FROMDT) AS TO_DATE
FROM @MYTABLE AS mt2
WHERE
mt2.BINGID = mt.BINGID
AND mt2.INDUSID = mt.INDUSID
AND mt2.COMP1 = mt.COMP1
AND mt2.FROMDT > mt.FROMDT
ORDER BY mt2.FROMDT
) AS oa
WHERE
mt.INDUSID = '1002'
ORDER BY BINGID, INDUSID, COMP1, FROMDT;
Result
+---------+---------+-----------------------------+------------------+-----------+-----------------------------+-----------------------------+-------------+
| BINGID | INDUSID | DTSEARCH | COMP1 | LISTPRICE | FROMDT | TO_DATE | IsRowActive |
+---------+---------+-----------------------------+------------------+-----------+-----------------------------+-----------------------------+-------------+
| 1000001 | 1002 | 2016-03-03 02:22:18.0000000 | 0392347402 | 41.91 | 2015-12-18 06:45:14.0000000 | 2016-05-26 14:54:41.0000000 | 0 |
| 1000001 | 1002 | 2016-05-26 14:54:42.0000000 | 0392347402 | 54.71 | 2016-05-26 14:54:42.0000000 | 2016-07-15 06:34:44.0000000 | 0 |
| 1000001 | 1002 | 2016-07-15 06:34:45.0000000 | 0392347402 | 81.71 | 2016-07-15 06:34:45.0000000 | 2016-10-17 11:26:57.0000000 | 0 |
| 1000001 | 1002 | 2016-11-09 02:21:17.0000000 | 0392347402 | 81.92 | 2016-10-17 11:26:58.0000000 | 9999-12-31 00:00:00.0000000 | 1 |
| 1000001 | 1002 | 2016-03-03 02:22:09.0000000 | 161GDB1577 | 37.17 | 2015-12-18 06:45:05.0000000 | 2016-05-26 14:54:27.0000000 | 0 |
| 1000001 | 1002 | 2016-05-26 14:54:28.0000000 | 161GDB1577 | 46.71 | 2016-05-26 14:54:28.0000000 | 2016-07-15 06:34:32.0000000 | 0 |
| 1000001 | 1002 | 2016-07-15 06:34:33.0000000 | 161GDB1577 | 52.48 | 2016-07-15 06:34:33.0000000 | 2016-10-17 11:26:44.0000000 | 0 |
| 1000001 | 1002 | 2016-10-17 11:26:45.0000000 | 161GDB1577 | 61.64 | 2016-10-17 11:26:45.0000000 | 2016-11-09 02:21:04.0000000 | 0 |
| 1000001 | 1002 | 2016-11-09 02:21:05.0000000 | 161GDB1577 | 78.35 | 2016-11-09 02:21:05.0000000 | 9999-12-31 00:00:00.0000000 | 1 |
| 1000005 | 1002 | 2018-11-09 02:21:05.0000000 | 556556GHB | 78.35 | 2018-11-09 02:21:05.0000000 | 9999-12-31 00:00:00.0000000 | 1 |
| 1002285 | 1002 | 2016-03-03 04:10:58.0000000 | 0026PU009163-031 | 77.76 | 2015-12-19 12:51:49.0000000 | 2016-05-27 12:14:52.0000000 | 0 |
| 1002285 | 1002 | 2016-05-27 12:14:53.0000000 | 0026PU009163-031 | 85.22 | 2016-05-27 12:14:53.0000000 | 2016-07-20 06:44:36.0000000 | 0 |
| 1002285 | 1002 | 2016-07-20 06:44:37.0000000 | 0026PU009163-031 | 90.39 | 2016-07-20 06:44:37.0000000 | 2016-10-18 13:49:09.0000000 | 0 |
| 1002285 | 1002 | 2016-11-09 13:37:13.0000000 | 0026PU009163-031 | 131.45 | 2016-10-18 13:49:10.0000000 | 9999-12-31 00:00:00.0000000 | 1 |
| 1002285 | 1002 | 2015-12-19 12:51:41.0000000 | 10122374 | 65.14 | 2015-12-19 12:51:41.0000000 | 2016-03-03 04:11:00.0000000 | 0 |
| 1002285 | 1002 | 2016-03-03 04:11:01.0000000 | 10122374 | 117.21 | 2016-03-03 04:11:01.0000000 | 2016-05-27 12:14:44.0000000 | 0 |
| 1002285 | 1002 | 2016-05-27 12:14:45.0000000 | 10122374 | 53.55 | 2016-05-27 12:14:45.0000000 | 2016-07-20 06:44:28.0000000 | 0 |
| 1002285 | 1002 | 2016-07-20 06:44:29.0000000 | 10122374 | 48.50 | 2016-07-20 06:44:29.0000000 | 2016-10-18 13:48:59.0000000 | 0 |
| 1002285 | 1002 | 2016-10-18 13:49:00.0000000 | 10122374 | 75.68 | 2016-10-18 13:49:00.0000000 | 2016-11-09 13:37:01.0000000 | 0 |
| 1002285 | 1002 | 2016-11-09 13:37:02.0000000 | 10122374 | 68.24 | 2016-11-09 13:37:02.0000000 | 9999-12-31 00:00:00.0000000 | 1 |
+---------+---------+-----------------------------+------------------+-----------+-----------------------------+-----------------------------+-------------+
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With