MSSQL导出表,其中一些列为空

时间:2018-01-19 00:54:04

标签: sql sql-server tsql

所以我需要从sql生成一个csv,如下所示:

Class   Teacher    email     Student    email
3Sci    Mr A       a@c.com   James      James@s.com
                             Mary       Mary@s.com
                             Joseph     Joe@s.com
4Eng    Mr B       b@c.com   William    William@s.com
                             James      James@s.com
                             Mary       Mary@s.com

等等。 我能用SQL获得以下内容:

3Sci    Mr A       a@c.com   James      James@s.com
3Sci    Mr A       a@c.com   Mary       Mary@s.com
3Sci    Mr A       a@c.com   Joseph     Joe@s.com
4Eng    Mr B       b@c.com   William    William@s.com
4Eng    Mr B       b@c.com   James      James@s.com
4Eng    Mr B       b@c.com   Mary       Mary@s.com

我的问题是,是否有人知道如何删除这些重复项而不删除整行?如果我可以这样做,那么我将能够将它全部导出到csv。我知道这不是一个非常好的桌面结构,但这是第三方对我的要求。

2 个答案:

答案 0 :(得分:1)

通常我建议在应用层中执行此操作。但您可以使用窗口函数在SQL中对此进行点击:

with t as (
      <your query here>
    )
select (case when seqnum = 1 then t.Class end) as class,
       (case when seqnum = 1 then t.Teacher end) as teacher,
       (case when seqnum = 1 then t.email end) as email,
       t.Student, t.email
from (select t.*,
             row_number() over (partition by t.Class, t.Teacher, t.email order by t.Student) as seqnum
      from t
     ) t
order by t.Class, t.Teacher, t.email, seqnum;

请注意外部查询中的order by。这是非常重要的。除非您有order by,否则SQL不保证结果集的排序。而且,排序对于解释生成的文件非常重要。

如果NULL值未输出为空白,则使用else ''输出空字符串。

答案 1 :(得分:0)

在SQL Server中,您可以使用带有rownumber的CTE来清除值。这是一个例子:

; WITH cteMain AS
(
    SELECT '1' AS A, 'r' AS B, 't' AS C
    UNION
    SELECT '1' AS A, 'r' AS B, 'a' AS C
    UNION
    SELECT '2' AS A, 'y' AS B, 'a' AS C
    UNION
    SELECT '2' AS A, 'i' AS B, 'u' AS C
),
cteGrouped AS
(
    SELECT *, 
    ROW_NUMBER() OVER (ORDER BY A, B, C) AS RowNumber
    FROM cteMain
),
cteOptimised AS
(
    SELECT 
        CASE ( SELECT G2.A FROM cteGrouped G2 WHERE G1.RowNumber > 1 AND G2.RowNumber = (G1.RowNumber-1) ) WHEN G1.A THEN '' ELSE G1.A END AS A,
        CASE ( SELECT G2.B FROM cteGrouped G2 WHERE G1.RowNumber > 1 AND G2.RowNumber = (G1.RowNumber-1) ) WHEN G1.B THEN '' ELSE G1.B END AS B,
        CASE ( SELECT G2.C FROM cteGrouped G2 WHERE G1.RowNumber > 1 AND G2.RowNumber = (G1.RowNumber-1) ) WHEN G1.C THEN '' ELSE G1.C END AS C
    FROM cteGrouped G1
)
SELECT *
FROM cteOptimised