我正在为一组TO_DATE
,BINGID
,INDUSID
计算COMP1
列。
当IsRowActive = 1
然后TO_DATE
=“9999-12-31”时,正确返回。
但是当IsRowActive = 0
时,我们必须计算To_Date
,它应该比下一个FROMDT
小1秒
数据:
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
我试过查询 - 遗憾的是它返回了错误的数据:
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'
预期输出
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
感谢。
答案 0 :(得分:2)
试试这个简单易读的解决方案,使用CTE
和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
答案 1 :(得分:2)
我真的很喜欢@Chanukya的回答。但是当您使用2008时,您将无法使用LEAD功能。相反,您可以使用自联接:
-- 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
;
逻辑类似于你的外部应用,但它应该表现得更好。这是因为没有correlation。
样本数据提出了一个小挑战。因为有两个FROMDT
2016-07-20 06:44:37.0000000
的记录,你可以说我的结果是错误的。
答案 2 :(得分:1)
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
输出
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
答案 3 :(得分:1)
而不是<?php function hide_error() { ?>
<style type="text/css">
.login #login_error{
display: none;
}
</style>
<?php }
add_action( 'login_enqueue_scripts', 'hide_error' ); ?>
在MAX
中使用TOP(1)
而ORDER BY
使用OUTER APPLY
。
另外,您说要按BINGID, INDUSID, COMP1
进行分组,因此请使用WHERE
中OUTER APPLY
子句中的所有这些列。为什么在查询中省略COMP1
?
示例数据
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
<强>查询强>
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;
<强>结果强>
+---------+---------+-----------------------------+------------------+-----------+-----------------------------+-----------------------------+-------------+
| 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 |
+---------+---------+-----------------------------+------------------+-----------+-----------------------------+-----------------------------+-------------+
答案 4 :(得分:-1)
使用CTE +联接:
最后,解决方案就在这里。 结果数据最终根据您的要求准确,您也可以使用[列名]的顺序更改序列。
代码:
with cte as
(
SELECT
ROW_NUMBER( ) OVER ( partition by COMP1 ORDER BY (SELECT 1))
rowno,
BINGID,
INDUSID,
DTSEARCH,
COMP1,
LISTPRICE,
FROMDT,
IsRowActive
FROM @MYTABLE mt
)
select c1.BINGID,c1.INDUSID, c1.DTSEARCH, c1.COMP1, c1.LISTPRICE, c1.FROMDT, c1.IsRowActive,
CASE WHEN c1.IsRowActive = 1 THEN '9999-12-31' ELSE case when ( c2.rowno is null ) THEN '9999-12-31'
else DATEADD(second, -1, coalesce(c2.FROMDT,'9999-12-31') ) End END
AS TO_DATE
from cte c1 left join cte c2
on c1.rowno+1= c2.rowno and c1.COMP1=c2.COMP1
order by c1.BINGID,DTSEARCH
还要检查Demo。