Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 слияние нескольких строк в одну  [new]
seeerg_23
Member

Откуда:
Сообщений: 1102
есть готовый код для сляния строк. ноя так понял это для 1й табл.

create table dbo.TEST ([Тип] INTEGER, [Имя] NVARCHAR(100), [Количество] INTEGER)
go
INSERT dbo.TEST VALUES(1, N'Молоко', 5)
INSERT dbo.TEST VALUES(1, N'Сметана', 6)
INSERT dbo.TEST VALUES(2, N'Гвозди', 44)
INSERT dbo.TEST VALUES(3, N'Машины', 1)

select [Тип] ,
(select [Имя]+ ',' as 'data()' from test t2 where t1.[Тип]=t2.[Тип] for xml path('') ) as Name, sum(количество)
from dbo.TEST t1
group by [Тип]

а если таблиц несколько, что у казывать в подзапросе FROM ???? всю связку таблиц ( inner join) ?? а что в гланом запросе FROM тоже самое ??
те задача такая: есть 3 табл тест1, тест2, тест3. из каждой выбираем по 1 полю: ТИП, ИМЯ, КОЛИЧЕСТВО. и задвоенные строки не в поле ТИП, а в поле ИМЯ. как теперь изменится запрос?? напишите, плз. как будут указываться t1 и t2 после FROM в запросе и в подзапросе.
26 июл 12, 16:19    [12920548]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
seeerg_23
Member

Откуда:
Сообщений: 1102
если это нельзя сделать подзапросом для полей разныз таблиц, тогда помогите, плз, функцию написать, которая будет это делать
26 июл 12, 17:05    [12920899]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37101
Чем помочь-то? Что не получается?
26 июл 12, 17:07    [12920924]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
user89
Member

Откуда:
Сообщений: 2083
seeerg_23
есть 3 табл тест1, тест2, тест3. из каждой выбираем по 1 полю: ТИП, ИМЯ, КОЛИЧЕСТВО.
Дайте данные для этих таблиц, примерно как здесь: 12398261
26 июл 12, 17:09    [12920933]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
seeerg_23
Member

Откуда:
Сообщений: 1102
таблица
ТИП--ИМЯ
1---молоко
1---сметана
2---гвозди

нужно данные повторяющихся строк перечислить в 1й строке. те должно быть так
ТИП--ИМЯ
1---молоко, сметана
2---гвозди
если это 1 табл, то запрос работает
select [Тип] ,
(select [Имя]+ ',' as 'data()' from test t2 where t1.[Тип]=t2.[Тип] for xml path('') ) as Name, sum(количество)
from dbo.TEST t1
group by [Тип]
если это 2 табл : поле ТИП - test1, поле ИМЯ - test2
обычный запрос будет выглядеть так:

select test1.тип, test2.имя
from test1 inner join test2 on test1.id = test2.id

как теперь для 2х таблиц сделать слияние повторяющихся строк??

select [Тип] ,
(select [Имя]+ ',' as 'data()' from test1 inner join test2 on test1.id = test2.id t2
where t1.[Тип]=t2.[Тип] for xml path(''))
from test1 inner join test2 on test1.id = test2.id t1
group by [Тип]

как будет выглядеть запрос для нескольких табл?? где будет указываться t1 и t1?? что указывать в 1м и 2м FROM - всю связку?
сейчас так не работает, выдаёт синтаксич ошибку.
26 июл 12, 17:34    [12921124]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
user89
Member

Откуда:
Сообщений: 2083
seeerg_23,

???

from test1 t1 inner join test2 t2 on t1.id = t2.id
26 июл 12, 17:37    [12921154]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
seeerg_23
Member

Откуда:
Сообщений: 1102
те надо и там и там указать?? не работает
select [Тип] ,
(select [Имя]+ ',' as 'data()' from test1 t1 inner join test2 t2 on test1.id = test2.id
where t1.[Тип]=t2.[Тип] for xml path(''))

from test1 t1 inner join test2 t1 on test1.id = test2.id
group by [Тип]
26 июл 12, 17:47    [12921217]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
user89
Member

Откуда:
Сообщений: 2083
seeerg_23,

Выполните этот запрос и приведите уже наконец тестовые данные:

declare @test1 table (id int, tip varchar(50), val varchar(max))
insert @test1
  select 1, 'Продукты', 'Хлеб' union all select 2, 'Продукты', 'Молоко' union all select 1, 'Инструменты', 'Рубанок' union all select 2, 'Инструменты', 'Отвертка'
select * from @test1

declare @test2 table (id int, tip varchar(50), val varchar(max))
insert @test2
  select 1, 'Продукты', 'Чай' union all select 2, 'Продукты', 'Конфеты' union all select 1, 'Инструменты', 'Кувалда' union all select 2, 'Инструменты', 'Дрель'
select * from @test2
26 июл 12, 18:33    [12921535]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
seeerg_23
Member

Откуда:
Сообщений: 1102
у меня данные уже есть в табл. зачем мне перебирать записи, когда нужно работать с полями, тк записи автоматически добавляются.
все посылают сюда https://www.sql.ru/faq/faq_topic.aspx?fid=130 но для нескольких табл я не знаю как сделать запрос из примера
--Вариант 1
select [Тип] ,( select [Имя]+': '+cast([Количество] as nvarchar)+ ',' as 'data()' from test t2 where t1.[Тип]=t2.[Тип] for xml path('') )
from dbo.TEST t1
group by [Тип]

нашёл подобное для своей задачи https://www.sql.ru/forum/actualthread.aspx?tid=493060&hl=%ea%ee%ed%ea%e0%f2%e5%ed%e0%f6%e8%ff%20%ed%e5%f1%ea%ee%eb%fc%ea%e8%f5%20%f1%f2%f0%ee%ea

DECLARE @t TABLE (id varchar(50), str1 varchar(250))
insert @t
select s.StorageNumber,
m.OriginalName
from Storages s with (NOLOCK)
left outer join dbo.Episodes e with (NOLOCK)
on s.StorageID = e.StorageID
left outer join dbo.VideoMaterials m with (NOLOCK)
on m.VideoMaterialID = e.VideoMaterialID
where s.IsDeleted = 0

DECLARE @t2 TABLE (id varchar(50))
insert @t2
select distinct
s.StorageNumber
from Storages s with (NOLOCK)
where s.IsDeleted = 0

select id,
(SELECT b.str1+'; ' 'data()' FROM @t b WHERE b.id = a.id FOR xml path(''))
from @t2 a

я не пойму где это писать?? это хранимая процедура?? и ещё если это для 2х полей, а если у меня 10 полей, а данные повторяются в 5 полях....?? тгда как ??
27 июл 12, 12:42    [12924745]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
user89
Member

Откуда:
Сообщений: 2083
seeerg_23,

эх, если бы Вы привели тестовые данные, как я выше, то задачу решили бы быстро.
А так...

Конструкция for xml path('') делает из таблицы одну строку. Пример:
declare @t table (s varchar(100))
insert @t select 'Яблоки' union all select 'Груши' union all select 'Апельсины'
select * from @t

select ', ' + s from @t for xml path('')


В Вашем случае возможно прокатит такой вариант.
Делаем join со всеми таблицами и результат пихаем во временную таблицу
select <Список нужных полей>
into #Res
from Таблица1 t1
inner join Таблица2 t2 on t1.tip = t2.tip
inner join Таблица3 t3 on ...

Далее работаем только с этой временной таблицей согласно FAQ.
Можно на #Res индексы повесить, чтобы склеивание строк происходило быстрее.
27 июл 12, 13:27    [12925097]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
XML на сервере моветон. Как временное костыльное решение.
27 июл 12, 15:15    [12926038]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
seeerg_23
Member

Откуда:
Сообщений: 1102
пример с яблоками не получится, тк я не знаю какие данные там будут и они меняются через время. вот реал пример на выборку.

SELECT IDSTINCT dbo.PC.Name, dbo.BIOS.Name, dbo.DISK.Model, dbo.DISK.Size/1024, dbo.CPU.Name0, dbo.CPU.Socket, dbo.MEMORY.Type, dbo.MEMORY.Size/1024

FROM dbo.BIOS INNER JOIN dbo.PC ON dbo.BIOS.ResourceID = dbo.PC.ResourceID INNER JOIN
dbo.DISK ON dbo.BIOS.ResourceID = dbo.DISK.ResourceID INNER JOIN
dbo.CPU ON dbo.DISK.ResourceID = dbo.CPU.ResourceID INNER JOIN
dbo.MEMORY ON dbo.PC.ResourceID = dbo.MEMORY.ResourceID

результат:

PC.........BIOS...........HDD.......HDD Size......CPU.......Socket......Memory Type...Memory Syze
sonya....default......samsung......100 Gb......Intel........775..........DIMM1............1024
olga......Phoenix........WD...........120 Gb......Intel........775..........DIMM1............2048
kolya.....default.......seagate......250 Gb......Intel........775..........DIMM1............1024
tanya....AMD..........Seagate......300 Gb.....AMD.........939...........DIMM1............3072
tanya....AMD..........Seagate......350 Gb.....AMD.........939...........DIMM1............1024
tanya....AMD..........Seagate......400 Gb.....AMD.........939...........DIMM1............2048

те, все табл соединены последовательно по одному полю ResourceID.
27 июл 12, 15:25    [12926097]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
user89
Member

Откуда:
Сообщений: 2083
seeerg_23,

вот-вот, уже ближе. Выполните
SELECT IDSTINCT dbo.PC.Name, dbo.BIOS.Name, dbo.DISK.Model, dbo.DISK.Size/1024, dbo.CPU.Name0, dbo.CPU.Socket, dbo.MEMORY.Type, dbo.MEMORY.Size/1024
into #Res
FROM dbo.BIOS INNER JOIN dbo.PC ON dbo.BIOS.ResourceID = dbo.PC.ResourceID INNER JOIN
 dbo.DISK ON dbo.BIOS.ResourceID = dbo.DISK.ResourceID INNER JOIN
 dbo.CPU ON dbo.DISK.ResourceID = dbo.CPU.ResourceID INNER JOIN
 dbo.MEMORY ON dbo.PC.ResourceID = dbo.MEMORY.ResourceID

select * from #Res

Далее мучаем только таблицу #Res

+ Как еще я могу помочь

Оформите вот этот текст
PC.........BIOS...........HDD.......HDD Size......CPU.......Socket......Memory Type...Memory Syze
sonya....default......samsung......100 Gb......Intel........775..........DIMM1............1024
olga......Phoenix........WD...........120 Gb......Intel........775..........DIMM1............2048
kolya.....default.......seagate......250 Gb......Intel........775..........DIMM1............1024
tanya....AMD..........Seagate......300 Gb.....AMD.........939...........DIMM1............3072
tanya....AMD..........Seagate......350 Gb.....AMD.........939...........DIMM1............1024
tanya....AMD..........Seagate......400 Gb.....AMD.........939...........DIMM1............2048


в виде
select 'sonya' as PC, 'default' as BIOS, ...
union all select 'olga' union all 'Phoenix' union all ...

и что должно получиться в итоге.
Тогда я или кто-то еще напишет решение.
27 июл 12, 16:01    [12926397]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
kinglion
Member

Откуда:
Сообщений: 16
;WITH [tables] ([type], [name], [count]) AS (
SELECT [type], [name], [count] FROM t1 WHERE ...
UNION SELECT [type], [name], [count] FROM t1 WHERE ...
UNION SELECT [type], [name], [count] FROM t1 WHERE ...
...
)
SELECT [type] ,(SELECT [name]+ ',' AS 'data()' FROM [tables] t2 WHERE t1.[type]=t2.[type] FOR XML PATH('') ) AS name, SUM([count])
FROM [tables] t1
GROUP BY [type]
27 июл 12, 20:06    [12927577]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
seeerg_23
Member

Откуда:
Сообщений: 1102
PC.........BIOS...........HDD.......HDD Size......CPU.......Socket......Memory Type...Memory Syze
sonya....default......samsung......100 Gb......Intel........775..........DIMM1............1024
olga......Phoenix........WD...........120 Gb......Intel........775..........DIMM1............2048
kolya.....default.......seagate......250 Gb......Intel........775..........DIMM1............1024
tanya....AMD..........Seagate......300 Gb.....AMD.........939...........DIMM1............3072
tanya....AMD..........Seagate......350 Gb.....AMD.........939...........DIMM1............1024
tanya....AMD..........Seagate......400 Gb.....AMD.........939...........DIMM1............2048

c into #res - не получилось, результат тот же, новые или доп или повторяющиеся данные в новой строке. таблица должна получиться так:

PC.........BIOS...........HDD.......HDD Size......CPU.......Socket......Memory Type...Memory Syze
sonya....default......samsung......100 Gb......Intel........775..........DIMM1............1024
olga......Phoenix........WD...........120 Gb......Intel........775..........DIMM1............2048
kolya.....default.......seagate......250 Gb......Intel........775..........DIMM1............1024
tanya....AMD..........Seagate..300 Gb, Seagate..350 Gb, Seagate..400 Gb.....AMD...939.....DIMM1...3072, DIMM1...1024, DIMM1...2048

те повторяющиеся (или доп) данные должны печисляться в одной строке.

для запроса с ;with..... xml path ('') не понятно как будет выглядеть запрос с несколькими таблицами и выборкой по нескольким полям
30 июл 12, 09:52    [12932947]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
Glory
Member

Откуда:
Сообщений: 104760
seeerg_23
для запроса с ;with..... xml path ('') не понятно как будет выглядеть запрос с несколькими таблицами и выборкой по нескольким полям

Так же, как и с одной таблицей
30 июл 12, 10:09    [12933037]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
seeerg_23
Member

Откуда:
Сообщений: 1102
можно пример?? тк мне не понятно
30 июл 12, 10:12    [12933054]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
Glory
Member

Откуда:
Сообщений: 104760
https://www.sql.ru/faq/faq_topic.aspx?fid=130
30 июл 12, 10:22    [12933109]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
seeerg_23
Member

Откуда:
Сообщений: 1102
я поршу помочь с моим примером, тк у меня несколько таблиц и несколько полей. как будет выглядеть запрос для моего примера??
30 июл 12, 10:25    [12933134]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
Glory
Member

Откуда:
Сообщений: 104760
seeerg_23
я поршу помочь с моим примером, тк у меня несколько таблиц и несколько полей. как будет выглядеть запрос для моего примера??

Точно также
Какая разница, сколько таблиц во FROM ?
30 июл 12, 10:30    [12933156]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
seeerg_23
Member

Откуда:
Сообщений: 1102
вот мне и не понятно в первом FROM и во втором FROM c t1 и t2, и t3 и тд, где и что указывать.
30 июл 12, 10:35    [12933177]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
Glory
Member

Откуда:
Сообщений: 104760
seeerg_23
вот мне и не понятно в первом FROM и во втором FROM c t1 и t2, и t3 и тд, где и что указывать.

И там и там придется указывать все. Это же коррелированные запросы.
Если не поняли идею запросо, то поместите резултьта запроса в промежуточную таблицу. И уже для нее делайте запрос с FOR XML PATH
30 июл 12, 10:39    [12933188]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
seeerg_23
Member

Откуда:
Сообщений: 1102
сделал, выдаёт синтаксич ошибку: incorrect syntax near the keyword 'AS'

SELECT IDSTINCT dbo.PC.Name, dbo.BIOS.Name, dbo.DISK.Model, dbo.DISK.Size/1024, dbo.CPU.Name0, dbo.CPU.Socket, dbo.MEMORY.Type, dbo.MEMORY.Size/1024
into #Res
FROM dbo.BIOS INNER JOIN dbo.PC ON dbo.BIOS.ResourceID = dbo.PC.ResourceID INNER JOIN
dbo.DISK ON dbo.BIOS.ResourceID = dbo.DISK.ResourceID INNER JOIN
dbo.CPU ON dbo.DISK.ResourceID = dbo.CPU.ResourceID INNER JOIN
dbo.MEMORY ON dbo.PC.ResourceID = dbo.MEMORY.ResourceID

select dbo.PC.Name, (dbo.DISK.Model + ',' as 'data()' from #Res t2 where t1.[PC.Name]=t2.[PC.Name])
from #Res t1
30 июл 12, 11:24    [12933417]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
Glory
Member

Откуда:
Сообщений: 104760
seeerg_23
select dbo.PC.Name, (dbo.DISK.Model + ',' as 'data()' from #Res t2 where t1.[PC.Name]=t2.[PC.Name])
from #Res t1

Что теперь то мешает взять запрос из FAQ и подставить в него имена своей таблицы и полей ?
30 июл 12, 11:32    [12933457]     Ответить | Цитировать Сообщить модератору
 Re: слияние нескольких строк в одну  [new]
user89
Member

Откуда:
Сообщений: 2083
seeerg_23,

На таких данных
PCBIOSHDDHDD_SizeCPUSocketMemory_TypeMemory_Size
sonyadefaultsamsung100 GbIntel775DIMM11024
olgaPhoenixWD120 GbIntel775DIMM12048
kolyadefaultseagate250 GbIntel775DIMM11024
tanyaAMDSeagate300 GbAMD939DIMM13072
tanyaAMDSeagate350 GbAMD939DIMM11024
tanyaAMDSeagate400 GbAMD939DIMM12048

+ можно так
set nocount on

declare @t table (PC varchar(50), BIOS varchar(50), HDD varchar(50), HDD_Size varchar(50), CPU varchar(50), Socket int, Memory_Type varchar(50), Memory_Size int)
insert @t
  select 'sonya', 'default', 'samsung', '100 Gb', 'Intel', 775, 'DIMM1', 1024 union all
  select 'olga', 'Phoenix', 'WD', '120 Gb', 'Intel', 775, 'DIMM1', 2048 union all
  select 'kolya', 'default', 'seagate', '250 Gb', 'Intel', 775, 'DIMM1', 1024 union all
  select 'tanya', 'AMD', 'Seagate', '300 Gb', 'AMD', 939, 'DIMM1', 3072 union all
  select 'tanya', 'AMD', 'Seagate', '350 Gb', 'AMD', 939, 'DIMM1', 1024 union all
  select 'tanya', 'AMD', 'Seagate', '400 Gb', 'AMD', 939, 'DIMM1', 2048

if object_id('tempdb..#res') is not null drop table #res
select * into #res from @t
select * from #res

select pc, bios,
substring((
  select ', '+ t2.hdd +' '+ t2.hdd_size from #res t2 where t2.pc = t1.pc and t2.bios = t1.bios for xml path('')),
2, 2000000000) [hdd],
cpu, socket, substring((
  select ', '+ t2.Memory_Type +' '+ cast(t2.Memory_Size as varchar(50)) from #res t2
  where t2.pc = t1.pc and t2.cpu = t1.cpu and t2.socket = t1.socket for xml path('')),
2, 2000000000) [mem]
from #res t1
group by pc, bios, cpu, socket

if object_id('tempdb..#res') is not null drop table #res

Результат
pcbioshddcpusocketmem
kolyadefault seagate 250 GbIntel775 DIMM1 1024
olgaPhoenix WD 120 GbIntel775 DIMM1 2048
sonyadefault samsung 100 GbIntel775 DIMM1 1024
tanyaAMD Seagate 300 Gb, Seagate 350 Gb, Seagate 400 GbAMD939 DIMM1 3072, DIMM1 1024, DIMM1 2048
30 июл 12, 12:37    [12933886]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить