将连续的项目连成一行?

时间:2018-04-13 18:19:33

标签: sql sql-server

我有一个看起来像这样的表,并且不知道我如何编写查询以仅检索连续的项目。



<table>
  <tr>
    <th>Section</th>
    <th>Number</th>
    <th>Id</th>
  </tr>
  <tr>
    <td>1</td>
    <td>1</td>
    <td>1</td>
  </tr>
    <tr>
    <td>1</td>
    <td>2</td>
    <td>1</td>
  </tr>
    <tr>
    <td>1</td>
    <td>3</td>
    <td>2</td>
  </tr>
    <tr>
    <td>1</td>
    <td>4</td>
    <td>1</td>
  </tr>
    <tr>
    <td>2</td>
    <td>5</td>
    <td>1</td>
  </tr>
    <tr>
    <td>2</td>
    <td>6</td>
    <td>2</td>
  </tr>
    <tr>
    <td>2</td>
    <td>7</td>
    <td>1</td>
  </tr>
    <tr>
    <td>2</td>
    <td>8</td>
    <td>1</td>
  </tr>
</table>
&#13;
&#13;
&#13;

有没有办法查询此表并提取看起来像这样的数据?

Section    Items
1          1-2, 4
2          5, 7-8

我们在哪里排除ID不为1的商品?

1 个答案:

答案 0 :(得分:2)

您可以使用CTE和Dense_Rank来实现此目的:

--setting up data 
DECLARE @t TABLE
(
section int,
number int, 
id int
)

insert into @t
values(1,1,1),
(1,2,1),
(1,3,2),
(1,4,1),
(2,5,1),
(2,6,2),
(2,7,1),
(2,8,1)

--Query
;WITH cte
AS (
    SELECT SECTION,
       number,
       DR = number - DENSE_RANK() OVER(ORDER BY number)
    FROM @t
    WHERE id <> 2
    GROUP BY SECTION,
          number
)
SELECT SECTION,
    STUFF(
          (
             SELECT ', '+CASE
                          WHEN MIN(number) <> MAX(number)
                          THEN CAST(MIN(number) AS VARCHAR(MAX))+'-'+CAST(MAX(number) AS VARCHAR(MAX))
                          ELSE CAST(MAX(number) AS VARCHAR(MAX))
                       END
             FROM cte
             WHERE SECTION = Results.SECTION
             GROUP BY SECTION,
                       DR FOR XML PATH(''), TYPE
          ).value('(./text())[1]', 'VARCHAR(MAX)'), 1, 2, ''
       ) AS Items
FROM cte Results
GROUP BY SECTION;