Как выбрать значение в виде строки из столбца периода? - PullRequest
0 голосов
/ 08 июня 2019

У меня есть таблица для свойств заказа продукта.

OrderId     |  SerialFrom        |  Serial To
1           |  6605181145833976  |  6605181145833980

Как я могу показать это следующим образом:

SerialId
6605181145833976
6605181145833977
6605181145833978
6605181145833979

Спасибо.

Ответы [ 2 ]

1 голос
/ 08 июня 2019

Вам нужен рекурсив CTE как

CREATE TABLE Data(
  OrderId INT,
  SerialFrom BIGINT,
  SerialTo BIGINT
);

INSERT INTO Data VALUES
(1, 6605181145833976, 6605181145833980);

WITH CTE AS
(
  SELECT SerialFrom
  FROM Data
  UNION ALL
  SELECT SerialFrom + 1
  FROM CTE
  WHERE CTE.SerialFrom < 6605181145833979
)
SELECT SerialFrom SerialId
FROM CTE;

Возвращает:

+------------------+
|     SerialId     |
+------------------+
| 6605181145833976 |
| 6605181145833977 |
| 6605181145833978 |
| 6605181145833979 |
+------------------+

Так как число строк известно, и это только 4 значения, вы также можете использовать Table Value Constructor (что является лучшим выбором в данном случае) как

SELECT SerialFrom + Number SerialId
FROM Data D CROSS JOIN 
     (VALUES (0), (1), (2), (3)) T(Number);

Вы также можете сделать то же самое с master..spt_values системной таблицей, как

SELECT SerialFrom + Number SerialId
FROM Data D CROSS JOIN 
     master..spt_values T
WHERE T.[Type] = 'P'
      AND
      [Number] <= 3;

Кроме того, я рекомендую не использовать master..spt_values системную таблицу, поскольку она не документирована, и недокументированные системные таблицы могут быть изменены Microsoft без предупреждения, поэтому следует избегать их использования. Тем не менее это ваш выбор:).

Наконец, вот db<>fiddle, чтобы поиграть и посмотреть, как это работает.

0 голосов
/ 08 июня 2019

Подсчет чисел поможет. Это может быть предопределенная таблица или созданная на лету, как в запросе ниже.

with L0(N) as (
    select top(10) null from sys.all_objects
),L1(N) as (--  10**2
    select null 
    from L0 a1
    cross join L0 a2
),L2(N) as (--  10**2**2
    select null 
    from L1 a1
    cross join L1 a2
), tally as(
        select n = row_number() over(order by N) - 1
        from L2
)
select OrderId, SerialFrom + n 
from Mytable mt
join tally t on t.n <= SerialTo - SerialFrom 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...