SQL Как сгруппировать по двум разным столбцам, которые содержат одинаковые данные - PullRequest
0 голосов
/ 11 мая 2019

Как сгруппировать следующие данные вместе.
Обратите внимание, что идентичные данные могут находиться в разных столбцах, а также в одном и том же столбце.

| Id | Mobile | Home   |
| 1  | NULL   | 626... | 
| 2  | 626... | NULL   |
| 3  | 405... | NULL   |
| 4  | NULL   | 405... |
| 5  | 626... | 405... |
| 6  | 405... | 626... |

такой, что он дает этот результат

| GroupId | Id |
| 1       | 1  |
| 1       | 2  |
| 1       | 5  |
| 1       | 6  |

| 2       | 3  |
| 2       | 4  | 
| 2       | 5  | 
| 2       | 6  | 


GroupId может быть случайно сгенерированным идентификатором, например. NEWID (), он используется для определения «дубликатов» в разных столбцах
Нулевые значения игнорируются.

Ответы [ 3 ]

0 голосов
/ 23 мая 2019

Извиняюсь, поскольку мне трудно объяснить, чего я пытался достичь.Если кто-то сталкивался с этим, пожалуйста, посмотрите, является ли это потенциальным решением

;WITH CTE AS (
  SELECT * 
  FROM (
    VALUES(1, NULL, 626456),
    (2, 626456, NULL),
    (3, 405123, NULL),
    (4, NULL, 405123),
    (5, 626456, 405123),
    (6, 405123, 626456)) AS tbl (id, mobile, home)
),
PivotCte AS (
  SELECT  DISTINCT pvt.value
  FROM    CTE
  CROSS   APPLY (VALUES('mobile', mobile), ('home', home)) AS pvt (phone, value)
)
SELECT DENSE_RANK() OVER (ORDER BY p.value) as gid, c.id
FROM   CTE c
INNER JOIN PivotCte p ON c.mobile = p.value OR c.home = p.value

DB Fiddle

0 голосов
/ 23 мая 2019

Выполните UNION ALL двух проекций базовой таблицы.В этих проекциях строки, содержащие NULL в столбцах MOBILE и HOME соответственно, исключаются.Затем примените функцию DENSE_RANK к набору результатов.

WITH
  t AS (
    SELECT * 
    FROM (
      VALUES(1, NULL, 626456),
      (2, 626456, NULL),
      (3, 405123, NULL),
      (4, NULL, 405123),
      (5, 626456, 405123),
      (6, 405123, 626456)
    ) AS t (id, mobile, home)
  ),
  u AS (
    SELECT id, mobile AS dr FROM t WHERE mobile IS NOT NULL
    UNION ALL
    SELECT id, home FROM t WHERE home IS NOT NULL
  )
SELECT
  DENSE_RANK() OVER(ORDER BY dr DESC) AS GroupId, Id
FROM u
ORDER BY GroupId, Id;

Выход:

+---------+----+
| GroupId | Id |
+---------+----+
|       1 |  1 |
|       1 |  2 |
|       1 |  5 |
|       1 |  6 |
|       2 |  3 |
|       2 |  4 |
|       2 |  5 |
|       2 |  6 |
+---------+----+
0 голосов
/ 11 мая 2019

Полагаю, вам нужно COALESCE, чтобы вернуть ненулевое значение из значений Mobile, Home, и на основе результата вы можете сгруппировать текст и создать GroupId.

Таким образом, вы можете применить COALESCE(Mobile, Home) и DENSE_RANK() OVER (ORDER BY.

Пожалуйста, найдите демо с примерами данных:

DECLARE @TestTable TABLE (Id INT, Mobile INT, Home INT);

INSERT INTO @TestTable (Id, Mobile, Home) VALUES
(1, NULL, 626456),
(2, 626456, NULL),
(3, 405123, NULL),
(4, NULL, 405123);

SELECT DENSE_RANK() OVER(ORDER BY COALESCE(Mobile, Home)) AS GroupId,
       Id
FROM @TestTable
ORDER BY Id

Здесь я использовал ORDER BY на основеCOALESCE результат, вы можете изменить его в соответствии с вашими потребностями бизнеса.

Демонстрация на дб <> скрипка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...