Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
空列值,但保持值等于使用SQL查询提供的数字_Sql_Sql Server - Fatal编程技术网

空列值,但保持值等于使用SQL查询提供的数字

空列值,但保持值等于使用SQL查询提供的数字,sql,sql-server,Sql,Sql Server,假设下表 ID Name RowNumber 2314 YY 1 213 XH 2 421 XD 3 123 AA 4 213 QQQ 5 12 WW 6 312 RR 7 123 GG 8 12 F 9 12 FF

假设下表

ID         Name     RowNumber
2314       YY       1
213        XH       2
421        XD       3
123        AA       4
213        QQQ      5
12         WW       6
312        RR       7
123        GG       8
12         F        9
12         FF       10
312        VV       11
12         BB       12
32         NN       13
43         DD       14
53         DD       15
658        QQQQ     16
768        GGG      17
我想根据以下条件将
Name
字段替换为空字符串:

  • 第一个和最后一个单元格值将不会被删除
  • 需要返回不在连续单元格中的值
  • 只保留n个细胞
  • 如果n小于或等于用户输入的数字,则不执行任何操作
  • 例如,如果用户输入5,则仅保留5个值,结果应为(或类似)-

    可能会有更多的记录

    我正在使用SQL Server,请尝试以下操作:

    --Number that user enter
    DECLARE @InputNumber INT
    DECLARE @WorkingNumber INT
    DECLARE @TotalRecords INT
    DECLARE @Devider INT
    SET @InputNumber = 5
    SET @WorkingNumber = @InputNumber -2
    --Assume @InputNumber greater than 2 and @TotalRecords greater than 4
    SELECT @TotalRecords = COUNT(*)
    FROM Table;
    
    SET @Devider = CONVERT(@TotalRecords, DECIMAL(18,2))/CONVERT(@WorkingNumber, DECIMAL(18,2));
    
    WITH Conditioned (RowNumber)
    AS
    (
     SELECT RowNumber
     FROM Table
     WHERE RowNumber = 1
     UNION
     SELECT T.RowNumber
     FROM (SELECT TOP 1 RowNumber
           FROM Conditioned
           ORDER BY RowNumber DESC) AS C
          INNER JOIN Table AS T ON CONVERT(CEILING(C.RowNumber + @Devider), INT) = T.RowNumber
    )
    SELECT T.Id, CASE WHEN C.RowNumber IS NULL THEN '' ELSE T.Name END, T.RowNumber
    FROM Table T
     LEFT OUTER JOIN Conditioned C ON T.RowNumber = C.RowNumber
    WHERE
    UNION RowNumber != @TotalRecords
    SELECT Id, Name, RowNumber
    FROM Table
    WHERE RowNumber = @TotalRecords
    

    以下内容适用于SQL Server 2012+,因为它使用running/cumulative
    SUM
    。该查询假定
    RowNumber
    列中的值从1到总行数顺序排列,没有间隙。如果您的数据不是这样,您可以使用
    ROW\u NUMBER
    生成它们

    • 计算给定数量的比率
      N
      和总行数(
      CTE\u比率
    • 计算此比率的运行总和,截断总和的小数部分(
      CTE\u组
    • 运行rum的每个整数值定义一组行,对每个组中的行重新编号(
      CTE_Final
    • 仅为每组的第一行保留
      Name
    为了更好地理解它的工作原理,在输出中包括中间列(Ratio、GroupNumber、rn)

    样本数据

    DECLARE @T TABLE ([ID] int, [Name] varchar(50), [RowNumber] int);
    
    INSERT INTO @T([ID], [Name], [RowNumber]) VALUES
    (2314, 'YY', 1)
    ,(213, 'XH', 2)
    ,(421, 'XD', 3)
    ,(123, 'AA', 4)
    ,(213, 'QQQ', 5)
    ,(12, 'WW', 6)
    ,(312, 'RR', 7)
    ,(123, 'GG', 8)
    ,(12, 'F', 9)
    ,(12, 'FF', 10)
    ,(312, 'VV', 11)
    ,(12, 'BB', 12)
    ,(32, 'NN', 13)
    ,(43, 'DD', 14)
    ,(53, 'DD', 15)
    ,(658, 'QQQQ', 16)
    ,(768, 'GGG', 17);
    
    DECLARE @N int = 5;
    
    查询

    WITH
    CTE_Ratio AS
    (
        SELECT
            ID
            ,Name
            ,RowNumber
            ,COUNT(*) OVER() AS TotalRows
            ,CAST(@N-1 AS float) / CAST(COUNT(*) OVER() AS float) AS Ratio
        FROM @T
    )
    ,CTE_Groups AS
    (
        SELECT
            ID
            ,Name
            ,RowNumber
            ,TotalRows
            ,ROUND(SUM(Ratio) OVER(ORDER BY RowNumber), 0, 1) AS GroupNumber
        FROM CTE_Ratio
    )
    ,CTE_Final AS
    (
        SELECT
            ID
            ,Name
            ,RowNumber
            ,TotalRows
            ,ROW_NUMBER() OVER(PARTITION BY GroupNumber ORDER BY RowNumber) AS rn
        FROM CTE_Groups
    )
    SELECT
        ID
        ,CASE WHEN rn=1 OR RowNumber = TotalRows THEN Name ELSE '' END AS Name
        ,RowNumber
    FROM CTE_Final
    ORDER BY RowNumber;
    
    结果

    +------+------+-----------+
    |  ID  | Name | RowNumber |
    +------+------+-----------+
    | 2314 | YY   |         1 |
    |  213 |      |         2 |
    |  421 |      |         3 |
    |  123 |      |         4 |
    |  213 | QQQ  |         5 |
    |   12 |      |         6 |
    |  312 |      |         7 |
    |  123 |      |         8 |
    |   12 | F    |         9 |
    |   12 |      |        10 |
    |  312 |      |        11 |
    |   12 |      |        12 |
    |   32 | NN   |        13 |
    |   43 |      |        14 |
    |   53 |      |        15 |
    |  658 |      |        16 |
    |  768 | GGG  |        17 |
    +------+------+-----------+
    

    您正在使用什么RDBMS?您所说的“第一个和最后一个单元格”是什么意思?表本质上是不排序的,所以除非指定了顺序(在sql语句中使用order by),否则“first”和“last”都没有意义。假设它是按行号ROK排序的,那么保留
    AA
    GG
    NN
    而不是例如
    QQQ
    的原因是什么,FF`and
    DD
    ?它可以是任何字符串。您已加入表。。ID不是主键,因为您可以看到问题..ID不是唯一的
    +------+------+-----------+
    |  ID  | Name | RowNumber |
    +------+------+-----------+
    | 2314 | YY   |         1 |
    |  213 |      |         2 |
    |  421 |      |         3 |
    |  123 |      |         4 |
    |  213 | QQQ  |         5 |
    |   12 |      |         6 |
    |  312 |      |         7 |
    |  123 |      |         8 |
    |   12 | F    |         9 |
    |   12 |      |        10 |
    |  312 |      |        11 |
    |   12 |      |        12 |
    |   32 | NN   |        13 |
    |   43 |      |        14 |
    |   53 |      |        15 |
    |  658 |      |        16 |
    |  768 | GGG  |        17 |
    +------+------+-----------+