我是在SQL Server中使用CTE查询的新手。我在网上的帮助下构建了此查询,以便开始构建我的更改日志"突出显示我的数据库中所做的更改。请参阅下面链接的示例。我想排除没有变化的行。你能帮忙解决这个问题吗?
11月改变的第3行有空白值。我希望这一行不显示。我也不想做像WHERE row1<>这样的事情。 '' AND row2<> '' AND row3<> ''等,因为我的最终查询将包含更多行。这可能吗?
答案 0 :(得分:2)
您可以使用以下选项。 下面使用COALESCE函数。
使用相同的数据,只是修改了sqlfiddle中的代码。
匹配时将CASE
语句返回NULL
并将数据类型转换为varchar,然后在其中使用COALESCE
下面修改过的脚本包含nTEXT列。您可以在DATALENGTH
子句中将COALESCE
与WHERE
一起使用。
<强>修改:强>
CREATE TABLE tblEmp
([memid] int, [empid] int, [name] varchar(50),[salary] int, [room] varchar(50), changedate datetime, ntxt ntext);
INSERT INTO tblEmp
([memid], [empid], [name], [salary], [room], [changedate], [ntxt])
VALUES
(41, 1, 'peter', 1000, 'Regency', '11/4/2012', ''),
(43, 1, 'peterz', 2000, 'Regency','11/5/2013', 'nn') ,
(44, 1, 'peterz', 2000, 'Regency','11/7/2013', '') ,
(45, 4, 'sally', 2001, 'Sheratio','11/2/2013', '') ,
(46, 4, 'sally', 2000, 'Sheraton','11/6/2013', ''),
(47, 1, 'peter', 3000, 'Regency','12/4/2013', '') ,
(48, 4, 'sallye', 2000,'Sheraton 1', '11/9/2013', '') ,
(49, 4, 'sally', 3000, 'Sheraton','11/6/2013', 'kljslkdjflkajslkjasdlkjalskjdlakjsdlkjasldjfk')
;
WITH cte AS
(
SELECT
empid,
name,
salary, room,
changedate,
ntxt,
rn=ROW_NUMBER()OVER(PARTITION BY empid ORDER BY changedate)
FROM tblemp
)
SELECT *
FROM
(
SELECT c1.empid, oldname=CASE WHEN c1.Name=c2.Name THEN NULL ELSE C1.Name END,
newname=CASE WHEN c1.Name=c2.Name THEN NULL ELSE C2.Name END,
oldsalary=CASE WHEN c1.salary=c2.salary THEN NULL ELSE C1.salary END,
newsalary=CASE WHEN c1.salary=c2.salary THEN NULL ELSE C2.salary END,
oldroom=CASE WHEN c1.Room=c2.Room THEN NULL ELSE C1.Room END,
newroom=CASE WHEN c1.room=c2.room THEN NULL ELSE C2.room END,
c2.changedate
, c2.ntxt
FROM cte c1 INNER JOIN cte c2
ON c1.empid=c2.empid AND c2.RN=c1.RN+1
) x
WHERE NOT (COALESCE(oldname, newname, CAST(oldsalary AS VARCHAR), CAST(newsalary AS VARCHAR), CAST(oldroom AS VARCHAR), CAST(newroom AS VARCHAR)) is null
AND DATALENGTH(ntxt) = 0)
ORDER BY ChangeDate DESC
答案 1 :(得分:0)
与SQL Server 2012略有不同的方法是在公用表表达式中使用LAG
以便能够逐行检测。 CTE基本上将每一行与前一行中的相关数据一起拉出,并在外部查询中进行直接比较以生成结果。
WITH cte AS (
SELECT
empid, changeDate,
LAG(name) OVER (PARTITION BY empid ORDER BY changeDate) oldname, name,
LAG(salary) OVER (PARTITION BY empid ORDER BY changeDate) oldsalary, salary,
LAG(room) OVER (PARTITION BY empid ORDER BY changeDate) oldroom, room
FROM tblEmp
)
SELECT empid,
CASE WHEN name<>oldname THEN oldname ELSE '' END oldname,
CASE WHEN name<>oldname THEN name ELSE '' END newname,
CASE WHEN salary<>oldsalary THEN oldsalary ELSE '' END oldsalary,
CASE WHEN salary<>oldsalary THEN salary ELSE '' END newsalary,
CASE WHEN room<>oldroom THEN oldroom ELSE '' END oldroom,
CASE WHEN room<>oldroom THEN room ELSE '' END newroom,
changeDate
FROM cte
WHERE oldname<>name OR oldsalary<>salary OR oldroom<>room
ORDER BY empid, changeDate;