Избежание дубликатов с помощью функции вещи и для пути XML - PullRequest
0 голосов
/ 25 марта 2019

У меня проблема с дубликатами, использующими сервер mysql с функцией stuff. База данных содержит несколько миллионов записей, и использование различных не подлежит сомнению (кажется, что запрос даже не обрабатывается).

Это моя структура базы данных:

PersonID    Freetext    Importance
PersonID    Freetext    Importance
PersonID    Freetext    Importance
PersonID    Freetext    Importance
PersonID    Freetext    Importance

Я использовал следующую структуру для этого запроса. Запрос работает нормально (относительно функции stuff), но возвращает дубликаты. Например, если пять идентификаторов одинаковы, запрос возвращает пять строк:

SELECT PersonID, Importance, Freetext = STUFF(
             (SELECT '~' + Freetext
              FROM TABLE t1
              WHERE t1.PersonID = t2.PersonID
              FOR XML PATH (''))
             , 1, 1, '') from TABLE t2
group By PersonID, Importance
order by Importance

Как этого избежать?

Я бы хотел, чтобы все свободные тексты, принадлежащие одному и тому же PersonID, были объединены в одну строку, упорядочив их так, чтобы строка, имеющая наименьшее значение, имела бы вначале свой свободный текст.

1 Ответ

2 голосов
/ 25 марта 2019

Просто угадываю (не могу быть уверен, что получим желаемый результат, не зная этого или исходных данных), но если вы хотите, чтобы FOR XML PATH перечислял значения в порядке важности (от наименьшего к наибольшему), вам нужно переместить ORDER BY:

SELECT PersonID, [Freetext] = STUFF(
       (SELECT '~' + Freetext
          FROM dbo.[TABLE] AS t1
          WHERE t1.PersonID = t2.PersonID
          ORDER BY Importance
          FOR XML PATH ('')
       ), 1, 1, '') 
FROM dbo.[Table] AS t2
GROUP BY PersonID;

Если вы хотите как-то включить важность, вам нужно объединить ее со свободным текстом; это не имело смысла во внешнем запросе или в группе (группа по важности фактически была причиной ваших дубликатов).

Если вам нужно предотвратить дублирование значений для свободного текста, вам нужно добавить группировку в подзапрос. Но это тоже сложно; Что делать, если у вас есть два одинаковых значения для свободного текста, но они были введены с разной важностью? Вы отбрасываете ту, которая имеет более высокую или низкую важность?

Возвращаясь к исходной проблеме, в SQL Server 2017 и выше вы можете использовать гораздо более простую (и более эффективную) структуру:

SELECT PersonID,  
       [Freetext] = STRING_AGG([Freetext],'~') WITHIN GROUP (ORDER BY Importance)
  FROM dbo.[Table]
  GROUP BY PersonID;
...