Подход, используемый Тарин для конкатенации SQL

У меня есть эта таблица в SQL:

pid           displayname   Group
-------------------------------------
d-5454-s34    name          Frans
d-5454-s34    sd            xyh
d-5454-s34    description   Group zen
d-5454-s34    member        xxxx
d-5454-s34    member        yyyy
d-5454-s34    member        zzzzz
d-5454-s34    member        uuuuu
d-5454-s45    name          He-man
d-5454-s45    sd            ygh
d-5454-s45    description   Group Comics
d-5454-s45    member        eeee
d-5454-s45    member        ffffff
e-3434-t45    name          Calvin
e-3434-t45    sd            trdg
e-3434-t45    description   test

и окончательный результат должен быть

pid                name          sd      descript          member
---------------------------------------------------------------------------

d-5454-s34        Frans         xyh      Group zen       xxxx; yyyy; zzzzz; uuuuu

d-5454-s45        He-man        ygh      Group Comics    eeee; ffffff

e-3434-t45        Calvin        trdg     test                 NULL

Я использовал подход Тарин, который вы можете увидеть по этой ссылке: Sql PIVOT и агрегат конкатенации строк

... а пока я хочу построить только конкатенированную строку так:

SELECT distinct a.pid, a.displayname, LEFT(r.[Description] , LEN(r.[Description])-1) [Description]
  FROM [Teste] a
    CROSS APPLY
(
    SELECT r.[description] + '; ' 
    FROM [Teste] r
    where a.[pid] = r.[pid]
      and a.[displayname] = r.[displayname]
    FOR XML PATH('')
) r ([Description])

но объединение члена занимает много времени, и это вызывает эту ошибку: Не удалось выделить место для объекта 'dbo.Large Object Storage System: 422858089496576' в базе данных 'tempdb', поскольку файловая группа 'PRIMARY' заполнена.

ЕСЛИ я использую небольшой набор (используя select top 100 в select r. [Description]), он дает следующую таблицу (это только часть таблицы):

      pid              displayname          descript          
    ---------------------------------------------------------------------------

    d-5454-s34        member              xxxx; xxxx; xxxx; xxxx; (and it keeps to repeat)

   d-5454-s34        member               yyyy; yyyy; yyyy; yyyy;  (and it keeps to repeat)

    d-5454-s45        member             eeee; eeee; eeee; eeee; (and it keeps to repeat)

    d-5454-s45        sd                  ygh; ygh;ygh;ygh;ygh;ygh;  (and it keeps to repeat)

он также не показывает отдельных pId, и он повторяет значения .. он не показывает разные значения для элемента для каждого идентификатора, ни отдельные значения для sd, description и name.

В дизайне вашего стола много проблем. Здесь происходит EAV, что довольно болезненно. У вас всегда есть строки name, sd, description и member для каждого идентификатора? Есть ли у вас и другие ценности? Одна из проблем EAV - это собрать информацию воедино осмысленным образом.

Sean Lange 25.06.2018 17:57

каждый идентификатор всегда заполнял имя, описание и SD. У каждого идентификатора может быть НОЛЬ (редкий), ОДИН или более участников.

graphene 25.06.2018 18:12

А имя, сд и описание всегда одно и только одно значение?

Sean Lange 25.06.2018 18:16

да: имя, SD и описание содержат одно и только одно значение. Под одним значением я подразумеваю для одного конкретного PID ... имя, SD и описание имеют только одну строку, а не больше строк для каждого PID. Но для конкретного PID у нас может быть 0 строк (не часто), 1 строка или более 1 строки для MEMBER. для ясности: PID d-5454-s45 содержит только одно значение для описания, имени и sd, но два значения для элемента (в примере это eeee и fffff). примечание: это pid, а не id, я забыл букву "p", извините за мою ошибку.

graphene 26.06.2018 11:14
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
4
63
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

select distinct может решить вашу проблему. Но у вас есть другие проблемы с вашей логикой.

Я думаю, это то, что вы хотите:

SELECT a.*, 
       (SELECT STUFF( (SELECT DISTINCT '; ' + r.[description]
                       FROM [tdt_AD_Teste] r
                       WHERE a.pid = r.pid AND
                             r.[displayname] = 'member'
                       FOR XML PATH('')
                      ), 1, 2, ''
                    )
       ) Description
FROM (SELECT a.pid,
             MAX(CASE WHEN a.displayname = 'name' then [group] end) as name,
             MAX(CASE WHEN a.displayname = 'sd' then [group] end) as sd,
             MAX(CASE WHEN a.displayname = 'description' then [group] end) as description
      FROM tdt_AD_Teste a
      GROUP BY a.pid
     ) a;

Внутри выделенного материала (WHERE a. [Id] = r. [Id] AND (...) он говорит, что. [Id] является недопустимым именем столбца. В выделенном отдельном назначенном имени нет псевдонима «a». . так .. еще одна упаковка? ...

graphene 25.06.2018 21:04

@graphene. . . a относится к псевдониму подзапроса во внешнем FROM.

Gordon Linoff 26.06.2018 03:31

он не работает, идентификатор в a.id на самом деле не является идентификатором таблицы ... это просто код (и вы можете видеть, что он повторяется в первой таблице). с вашим кодом он выдает эту ошибку: Недопустимое имя столбца 'id'. даже если я использую его в максимуме (случай, когда a.id = .......). он по-прежнему возвращает null для всей таблицы. Я заменил id на pid, чтобы не путать с идентификатором таблицы. И используя этот pid, он говорит, что недопустимое имя столбца 'pid', поскольку оно не было объявлено во втором FROM. Проверьте таблицы выше (в исходном посте).

graphene 26.06.2018 11:18

@graphene. . . Вопрос Ваш изначально имел id. Похоже, вы поменяли его на pid.

Gordon Linoff 26.06.2018 13:44

понятно. он работает как драгоценный камень. Можно ли порекомендовать книгу о передовых методах написания сценариев SQL? Спасибо! Престижность.

graphene 26.06.2018 14:14

@graphene, если этот ответ работает для вас, вы должны отметить это как ответ. Таким образом, респондент и все, кто бродит сюда на протяжении многих лет, знают, что этот ответ работает в данной ситуации.

Sean Lange 26.06.2018 15:34

Другие вопросы по теме