SQL Server 2016 - Как выбрать данные в качестве диапазона, если все остальные параметры совпадают - PullRequest
0 голосов
/ 18 февраля 2019

Входные данные:

| CustomerName | TelephoneNumber | AddressLine1             | AddressLine2             | AddressLine3             | PostCode            |
|--------------|-----------------|--------------------------|--------------------------|--------------------------|---------------------|
| Company A    | 02000000000     | Company A Address Line 1 | Company A Address Line 2 | Company A Address Line 3 | Company A Post Code |
| Company B    | 02000000001     | Company B Address Line 1 | Company B Address Line 2 | Company B Address Line 3 | Company B Post Code |
| Company A    | 02000000002     | Company A Address Line 1 | Company A Address Line 2 | Company A Address Line 3 | Company A Post Code |
| Company A    | 02000000003     | Company A Address Line 1 | Company A Address Line 2 | Company A Address Line 3 | Company A Post Code |
| Company C    | 02000000004     | Company C Address Line 1 | Company C Address Line 2 | Company C Address Line 3 | Company C Post Code |
| Company C    | 02000000005     | Company C Address Line 1 | Company C Address Line 2 | Company C Address Line 3 | Company C Post Code |
| Company C    | 02000000006     | Company C Address Line 1 | Company C Address Line 2 | Company C Address Line 3 | Company C Post Code |
| Company C    | 02000000007     | Company C Address Line 1 | Company C Address Line 2 | Company C Address Line 3 | Company C Post Code |

Ожидаемый результат:

| CustomerName | TelephoneNumber           | AddressLine1             | AddressLine2             | AddressLine3             | PostCode            |
|--------------|---------------------------|--------------------------|--------------------------|--------------------------|---------------------|
| Company A    | 02000000000               | Company A Address Line 1 | Company A Address Line 2 | Company A Address Line 3 | Company A Post Code |
| Company B    | 02000000001               | Company B Address Line 1 | Company B Address Line 2 | Company B Address Line 3 | Company B Post Code |
| Company A    | 02000000002 - 02000000003 | Company A Address Line 1 | Company A Address Line 2 | Company A Address Line 3 | Company A Post Code |
| Company C    | 02000000004 - 02000000007 | Company C Address Line 1 | Company C Address Line 2 | Company C Address Line 3 | Company C Post Code |

<!DOCTYPE html>
<html>
<head>
<style>
table {
  font-family: arial, sans-serif;
  border-collapse: collapse;
  width: 100%;
}

td, th {
  border: 1px solid #dddddd;
  text-align: left;
  padding: 8px;
}

tr:nth-child(even) {
  background-color: #dddddd;
}
</style>
</head>
<body>
<table>
  <tr>
    <th>CustomerName</th>
    <th>TelephoneNumber</th>
    <th>AddressLine1</th>
    <th>AddressLine2</th>
    <th>AddressLine3</th>
    <th>PostCode</th>
  </tr>
  <tr>
    <td>Company A</td>
    <td>02000000000</td>
    <td>Company A Address Line 1</td>
    <td>Company A Address Line 2</td>
    <td>Company A Address Line 3</td>
    <td>Company A Post Code</td>
  </tr>
  <tr>
    <td>Company B</td>
    <td>02000000001</td>
    <td>Company B Address Line 1</td>
    <td>Company B Address Line 2</td>
    <td>Company B Address Line 3</td>
    <td>Company B Post Code</td>
  </tr>
  <tr>
    <td>Company A</td>
    <td>02000000002</td>
    <td>Company A Address Line 1</td>
    <td>Company A Address Line 2</td>
    <td>Company A Address Line 3</td>
    <td>Company A Post Code</td>
  </tr>
  <tr>
    <td>Company A</td>
    <td>02000000003</td>
    <td>Company A Address Line 1</td>
    <td>Company A Address Line 2</td>
    <td>Company A Address Line 3</td>
    <td>Company A Post Code</td>
  </tr>
  <tr>
    <td>Company C</td>
    <td>02000000004</td>
    <td>Company C Address Line 1</td>
    <td>Company C Address Line 2</td>
    <td>Company C Address Line 3</td>
    <td>Company C Post Code</td>
  </tr>
  <tr>
    <td>Company C</td>
    <td>02000000005</td>
    <td>Company C Address Line 1</td>
    <td>Company C Address Line 2</td>
    <td>Company C Address Line 3</td>
    <td>Company C Post Code</td>
  </tr>
    <tr>
    <td>Company C</td>
    <td>02000000006</td>
    <td>Company C Address Line 1</td>
    <td>Company C Address Line 2</td>
    <td>Company C Address Line 3</td>
    <td>Company C Post Code</td>
  </tr>
    <tr>
    <td>Company C</td>
    <td>02000000007</td>
    <td>Company C Address Line 1</td>
    <td>Company C Address Line 2</td>
    <td>Company C Address Line 3</td>
    <td>Company C Post Code</td>
  </tr>
</table>

<br/>

<h2>Query should return this</h2>

<table>
  <tr>
    <th>CustomerName</th>
    <th>TelephoneNumber</th>
    <th>AddressLine1</th>
    <th>AddressLine2</th>
    <th>AddressLine3</th>
    <th>PostCode</th>
  </tr>
  <tr>
    <td>Company A</td>
    <td>02000000000</td>
    <td>Company A Address Line 1</td>
    <td>Company A Address Line 2</td>
    <td>Company A Address Line 3</td>
    <td>Company A Post Code</td>
  </tr>
  <tr>
    <td>Company B</td>
    <td>02000000001</td>
    <td>Company B Address Line 1</td>
    <td>Company B Address Line 2</td>
    <td>Company B Address Line 3</td>
    <td>Company B Post Code</td>
  </tr>
  <tr>
    <td>Company A</td>
    <td>02000000002 - 02000000003</td>
    <td>Company A Address Line 1</td>
    <td>Company A Address Line 2</td>
    <td>Company A Address Line 3</td>
    <td>Company A Post Code</td>
  </tr>
  <tr>
    <td>Company C</td>
    <td>02000000004 - 02000000007</td>
    <td>Company C Address Line 1</td>
    <td>Company C Address Line 2</td>
    <td>Company C Address Line 3</td>
    <td>Company C Post Code</td>
  </tr>
</table>
</body>
</html>

Мне нужно построить запрос, учитывая верхнюю таблицу данных, вторая таблица возвращается.Если все параметры соответствуют (CustomerName, AddressLine1, AddressLine2, AddressLine3 и PostCode) и номера телефонов являются последовательными, их можно сгруппировать как диапазон.Если они не являются последовательными, они должны быть показаны в отдельных строках.Предоставленные данные являются только образцом, поскольку в таблице несколько тысяч строк, поэтому решение должно быть динамическим, чтобы оно могло справиться с любым количеством комбинаций.

До сих пор я придумал следующий запрос:

SELECT TelephoneNumber, CustomerName, AddressLine1, Addressline2, AddressLine3, PostCode  
       LAG (TelephoneNumber, 1, 0) OVER (PARTITION BY CustomerName, AddressLine1, AddressLine2, AddressLine3, AddressLine4, PostCode ORDER BY CLI) AS PreviousTelephoneNumber
FROM DataTable
ORDER BY TelephoneNumber

Однако это вернуло мне только номер телефона для предыдущей записи с теми же параметрами (Customername, AddressLine1 и т. Д.).

Я не уверен, как отсюда идтичтобы выглядеть как второй стол.Любая помощь очень ценится.

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Вы хотите, чтобы телефонные номера были без пробелов, поэтому просто вычтите последовательность из них, чтобы получить постоянное значение.Остальное агрегация:

select CustomerName, AddressLine1, AddressLine2, AddressLine3, PostCode,
       (case when count(*) = 1 then min(TelephoneNumber)
             else concat(min(TelephoneNumber), '-', max(TelephoneNumber))
        end) as telephone_numbers
from (select t.*,
             row_number() over (partition by CustomerName order by TelephoneNumber) as seqnum
      from t
     ) t
group by CustomerName, AddressLine1, AddressLine2, AddressLine3, PostCode,
         (convert(decimal(38, 0) TelephoneNumber) - seqnum)
0 голосов
/ 18 февраля 2019

вы можете попробовать, как показано ниже, используя row_number() найти последовательный и непоследовательный номер, затем взять min и max для диапазона

 with cte as
(
select 'Company A' as CustomerName, 0200 as TelephoneNumber, 'A' as AddressLine1
union all 
select 'Company B',0201,'B' union all
select 'Company A',0202,'A' union all
select 'Company A',0203,'A' union all
select 'Company A',0204,'A'
)
 , cte2 as (SELECT
    *,row_number() over(partition by CustomerName order by TelephoneNumber) rn,
    row_number()over(order by TelephoneNumber) rn1
FROM cte
) select CustomerName,case when min(TelephoneNumber)=max(TelephoneNumber) then
  cast(min(TelephoneNumber) as varchar(500))
  else concat( cast( min(TelephoneNumber) as varchar(500)),'-',
  cast (max(TelephoneNumber)as varchar(500))) end as TelephoneNumber,AddressLine1
 from cte2 group by CustomerName,AddressLine1,rn1-rn

, как в вашем случае AddressLine2, AddressLine3, AddressLine4, PostCode также придет в группу и по выбору я просто сделаю демо, используя 3 столбца, поэтому я не учел те, что в моем запросе

CustomerName    TelephoneNumber     AddressLine1
Company A        200                 A
Company A        202-204             A
Company B        201                 B
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...