SQL Server – 如何删除一些列的行而不会中断logging的其余部分

I have it -- -- -- -- 01 A1 B1 99 01 A1 B1 98 02 A2 B2 97 02 A2 B2 96 I need this -- -- -- -- 01 A1 B1 99 98 02 A2 B2 97 96 ------------ 

我不能重复我将会出现在excel中的数据,我的结果应该如此。 在我的实际表格中,最后一列是表单的答复,第一列(不能重复的)是客户数据(电话,姓名等)。 这个“查询”的最终结果将填充“数据表”,并将以“xlsx”文件forms呈现。

感谢分享知识^^

如果你有SQL2012 +

 SELECT ISNULL(NULLIF(Column1,LAG(Column1) OVER(ORDER BY Column1)),'') ,ISNULL(NULLIF(Column2,LAG(Column2) OVER(ORDER BY Column1,Column2)),'') ,ISNULL(NULLIF(Column3,LAG(Column3) OVER(ORDER BY Column1,Column2,Column3)),'') ,Column4 FROM #mytable ORDER BY Column1,Column2,Column3,Column4 DESC 

这有点乱,但你可以在数据库中做到这一点。 你基本上做一个子查询,得到最小的值,然后将其join到常规表中,并将不匹配的值清空。 我创build了这样的样本集:

 CREATE TABLE mytable (N1 VARCHAR(2), A VARCHAR(2), B VARCHAR(2), N2 VARCHAR(2)) INSERT INTO mytable VALUES ('01', 'A1', 'B1', '99'), ('01', 'A1', 'B1', '98'), ('02', 'A2', 'B2', '97'), ('02', 'A2', 'B2', '96') 

然后得到这样的结果:

 SELECT CASE WHEN O.N2 = I.N2 THEN O.N1 ELSE '' END, CASE WHEN O.N2 = I.N2 THEN OA ELSE '' END, CASE WHEN O.N2 = I.N2 THEN OB ELSE '' END, O.N2 FROM (SELECT MAX(N2) AS N2, N1, A, B FROM mytable GROUP BY N1, A, B) I INNER JOIN mytable O ON OA = IA AND OB = IB AND O.N1 = I.N1 ORDER BY O.N1 ASC 

我们可以使用ROW_NUMBER来获取序列,并将序列大于1的所有行replace为''

 with CTE AS ( SELECT ID, ColumnA, ColumnB, value,ROW_NUMBER() over ( PARTITION by id order by id) as seq FROM tableA ) , CTE1 AS ( select id, ColumnA, ColumnB, value, seq from CTE where seq =1 UNION SELECT id ,'','', value , seq from CTE where seq >1 ) SELECT case when seq >1 THEN NULL ELSE id END as id, columnA, columnB, value from CTE1 

你可以使用查询来实现你想要的。

你没有提供DDL,所以我打算asume你的列分别被称为abcd

 ; WITH cte AS ( SELECT a , b , c , d , Row_Number() OVER (PARTITION BY a, b, c ORDER BY d) As sequence FROM your_table ) SELECT CASE WHEN sequence = 1 THEN a ELSE '' END As a , CASE WHEN sequence = 1 THEN b ELSE '' END As b , CASE WHEN sequence = 1 THEN c ELSE '' END As c , d FROM cte ORDER BY a , b , c , d 

我们的想法是为每一行分配一个增量计数器,在每次更改a + b + c后重新开始计数。

然后,我们使用条件语句来显示或不显示一个值(基本上只显示在每个组的第一个实例上)

分析ROW_NUMBER()函数对此ROW_NUMBER() 。 我已经填了专栏名称,因为你没有提供任何。 要按客户分配行号,请使用如下所示的内容:

 SELECT Name, Phone, Address, Response, ROW_NUMBER() OVER (PARTITION BY Name, Phone, Address ORDER BY Response) AS CustRow FROM myTable 

这将在每个客户内分配行号。 亲自尝试,我认为这是有道理的。

您可以将其放入子查询或CTE中,并且当您位于每个客户的第一行时,仅显示姓名,电话和地址等客户ID信息:

 SELECT CASE WHEN CustRow = 1 THEN Name ELSE '' END AS Name, CASE WHEN CustRow = 1 THEN Phone ELSE '' END AS Phone, CASE WHEN CustRow = 1 THEN Address ELSE '' END AS Address, Response FROM ( SELECT Name, Phone, Address, Response, ROW_NUMBER() OVER (PARTITION BY Name, Phone, Address ORDER BY Response) AS CustRow FROM myTable) custSubquery ORDER BY Name, Phone, Address 

custSubquery第二行的custSubquery是因为SQL Server要求所有子查询都是别名,即使别名没有被使用。

最重要的是确定你的最后一列将如何sorting显示,并确保它在ROW_NUMBER()函数和最终的ORDER BY

如果您需要更多帮助,请提供表格和栏目名称, 指定每个客户的结果sorting方式。