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

Откуда: Россия. Санкт-Петербург
Сообщений: 3181
Есть две таблицы: письма и тесты заголовков писем.
Если в таблице с тестами, скажем, 3 строки, то при добавлении 9 строк в таблицу писем необходимо, чтобы результат был таким:
Заголовок письма Текст письма
Тест заголовка 1 Текст письма
Тест заголовка 1 Текст письма
Тест заголовка 1 Текст письма
Тест заголовка 2 Текст письма
Тест заголовка 2 Текст письма
Тест заголовка 2 Текст письма
Тест заголовка 3 Текст письма
Тест заголовка 3 Текст письма
Тест заголовка 3 Текст письма

Подскажите, пожалуйста, как эту задачу можно решить с помощью select или update, если это возможно. Я пока кроме курсора выходов не вижу.
3 янв 18, 16:40    [21080272]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом, пожалуйста  [new]
xenix
Guest
Vsevolod V,
автор
SELECT L.*, H.*
FROM LETTERS L
CROSS JOIN HEADERS H

так?
3 янв 18, 16:44    [21080278]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом, пожалуйста  [new]
Vsevolod V
Member

Откуда: Россия. Санкт-Петербург
Сообщений: 3181
xenix,

Спасибо. Нет, не так. В вашем варианте будет 1 получателю отправлено 3 письма с разными заголовками. И в общей сложности будет 27 писем, а не 9

Заголовок письмаТекст письмаEmail
Тест заголовка 1Текст письмаburkov@mail.ru
Тест заголовка 1Текст письмаfoma@yandex.ru
Тест заголовка 1Текст письмаgurch@mail.ru
Тест заголовка 2Текст письмаborya@gmail.com
Тест заголовка 2Текст письмаs.krupko@mail.ru
Тест заголовка 2Текст письмаmashhod@yandex.ru
Тест заголовка 3Текст письмаvorobeva.2017@gmail.com
Тест заголовка 3Текст письмаvershinin@uralsibstal.com
Тест заголовка 3Текст письмаganediy@yandex.ru
3 янв 18, 17:00    [21080309]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом, пожалуйста  [new]
ntile,
Guest
declare @z table (id int identity, txt varchar(100))
declare @t table (id int identity, txt varchar(100))

insert into @z (txt)
values ('Тест заголовка 1'), ('Тест заголовка 2'), ('Тест заголовка 3')

insert into @t (txt)
values ('Текст письма 1'), ('Текст письма 2'), ('Текст письма 3'),('Текст письма 4'), ('Текст письма 5'), ('Текст письма 6'),('Текст письма 7') --, ('Текст письма 8'), ('Текст письма 9')

declare @cnt int = (select count(*) from @z)

--	
;with b as
	(select *, row_number()over(order by id) as n from @z),
c as
	(select *, ntile(@cnt)over(order by id) as n from @t)		 

select
	b.n
	,b.txt 
	,c.txt
from b inner join c on b.n=c.n


ntxttxt
1Тест заголовка 1Текст письма 1
1Тест заголовка 1Текст письма 2
1Тест заголовка 1Текст письма 3
2Тест заголовка 2Текст письма 4
2Тест заголовка 2Текст письма 5
3Тест заголовка 3Текст письма 6
3Тест заголовка 3Текст письма 7
3 янв 18, 17:03    [21080313]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом, пожалуйста  [new]
Vsevolod V
Member

Откуда: Россия. Санкт-Петербург
Сообщений: 3181
ntile,

Спасибо! Похоже на то что надо. Буду проверять
3 янв 18, 17:09    [21080322]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом, пожалуйста  [new]
Vsevolod V
Member

Откуда: Россия. Санкт-Петербург
Сообщений: 3181
ntile,

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

Я попробовал это сделать, но столкнулся с ошибкой: "Ссылка на столбец "mt_id" недопустима в аргументе для функции NTILE. Допускаются только ссылки на столбцы внешней области или изолированные выражения и вложенные запросы."


;with 
b as (select *, row_number()over(order by mtv_id, mt_id) as n from tMailTestValues), 
mails as (select *, ntile((select count(*) from tMailTestValues where mt_id = mt.mt_id))over(order by mt_id) as n from v_A_TasksMail tm join 
tMailTest mt on tm.m_id_template = mt.m_id)		 

select
	b.n,
	mails.n
from b inner join mails on b.n = mails.n
3 янв 18, 18:05    [21080375]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом, пожалуйста  [new]
ntile,
Guest
Vsevolod V
ntile,

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

Я попробовал это сделать, но столкнулся с ошибкой: "Ссылка на столбец "mt_id" недопустима в аргументе для функции NTILE. Допускаются только ссылки на столбцы внешней области или изолированные выражения и вложенные запросы."


;with 
b as (select *, row_number()over(order by mtv_id, mt_id) as n from tMailTestValues), 
mails as (select *, ntile((select count(*) from tMailTestValues where mt_id = mt.mt_id))over(order by mt_id) as n from v_A_TasksMail tm join 
tMailTest mt on tm.m_id_template = mt.m_id)		 

select
	b.n,
	mails.n
from b inner join mails on b.n = mails.n
Зачем это where в подзапросе ?
Вот так "работает"

;with b as
	(select *, row_number()over(order by id) as n from @z),
c as
	(select *, ntile((select count(*) from @z))over(order by id) as n from @t)		 

select
	b.n
	,b.txt 
	,c.txt
from b inner join c on b.n=c.n
3 янв 18, 18:20    [21080397]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом, пожалуйста  [new]
Vsevolod V
Member

Откуда: Россия. Санкт-Петербург
Сообщений: 3181
Давайте лучше заново более полно сформулирую задачу со своей структурой данных.

Таблицы:
1. v_A_TasksMail - таблица писем, каждое письмо относится к той или иной рассылке, все тесты проводятся в рамках рассылки так, что тесты одной рассылки не пересекаются с тестами другой.

m_id_parent - идентификатор рассылки

m_id m_addressFrom m_addressTo m_subject m_text m_nameFrom m_id_parent
1 'vova@yandex.ru''vasya@mail.ru''Поздравляем Вас с Новым Годом!''Добрый день! Примите наши теплый поздравления''Всеволод Гаврилов'22
2 'vova@yandex.ru''ivan@mail.ru''Поздравляем Вас с Новым Годом!''Добрый день! Примите наши теплый поздравления''Всеволод Гаврилов'22
3 'vova@yandex.ru''petr@mail.ru''Поздравляем Вас с Новым Годом!''Добрый день! Примите наши теплый поздравления''Всеволод Гаврилов'22
4 'gena@yandex.ru''masha@mail.ru''Услуги клининга в Санкт-Петербурге''Добрый день! Заказывайте клининг только у нас!''Всеволод Гаврилов'23
5 'gena@yandex.ru''dasha@mail.ru''Услуги клининга в Санкт-Петербурге''Добрый день! Заказывайте клининг только у нас!''Всеволод Гаврилов'23
6 'gena@yandex.ru''zinaida@mail.ru''Услуги клининга в Санкт-Петербурге''Добрый день! Заказывайте клининг только у нас!''Всеволод Гаврилов'23
7 'olga@yandex.ru''stepan@mail.ru''Фильтры воды для дома и дачи''Добрый день! Заказывайте фильтры воды только у нас!''Всеволод Гаврилов'24


2. tMailTest - Таблица тестов для рассылки, например, тест темы письма, тест имени отправителя и т.п. Одна рассылка может содержать несколько тестов

mt_id mt_name m_id_parent
1 'Тест заголовка письма' 22
2 'Тест заголовка письма' 23



3. tMailTestValues
mtv_id mt_id mtv_value
11'С Новым 2018 Годом!'
21'Поздравляем от всей души с Новым Годом'
31'От всей души поздравляем с Новым Годом'
42'Профессиональные услуги клининга!'
52'Позаботьтесь о чистоте в вашем доме'


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

m_id m_addressFrom m_addressTo m_subject m_text m_nameFrom m_id_parent
1 'vova@yandex.ru''vasya@mail.ru''С Новым 2018 Годом!''Добрый день! Примите наши теплый поздравления''Всеволод Гаврилов'22
2 'vova@yandex.ru''ivan@mail.ru''Поздравляем от всей души с Новым Годом''Добрый день! Примите наши теплый поздравления''Всеволод Гаврилов'22
3 'vova@yandex.ru''petr@mail.ru''От всей души поздравляем с Новым Годом''Добрый день! Примите наши теплый поздравления''Всеволод Гаврилов'22
4 'gena@yandex.ru''masha@mail.ru''Профессиональные услуги клининга!''Добрый день! Заказывайте клининг только у нас!''Всеволод Гаврилов'23
5 'gena@yandex.ru''dasha@mail.ru''Позаботьтесь о чистоте в вашем доме''Добрый день! Заказывайте клининг только у нас!''Всеволод Гаврилов'23
6 'gena@yandex.ru''zinaida@mail.ru''Профессиональные услуги клининга!''Добрый день! Заказывайте клининг только у нас!''Всеволод Гаврилов'23
7 'olga@yandex.ru''stepan@mail.ru''Фильтры воды для дома и дачи''Добрый день! Заказывайте фильтры воды только у нас!''Всеволод Гаврилов'24
3 янв 18, 19:08    [21080480]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом, пожалуйста  [new]
aleks222
Guest
Осподи, что за фуфло?!!

select new_m_subject = isnull( x.mtv_value, t.m_subject)
       , t.* 
  from  v_A_TasksMail as t 
          outer apply ( select top(1) * from tMailTestValues where mtv_id = t.m_id ) as x


ЗЫ. Я догадываюсь, что страдалец хочет "иного"... но суть та же.
4 янв 18, 07:13    [21081173]     Ответить | Цитировать Сообщить модератору
 Re: Помогите с запросом, пожалуйста  [new]
ntile,
Guest
Vsevolod V,

что б ты ещё скриптами всю эту "красоту" выкладывал, цены бы тебе не было :)

+
declare @v_A_TasksMail table (m_id int, m_addressFrom varchar(100), m_addressTo varchar(100), m_subject varchar(100), m_text varchar(100), m_nameFrom varchar(100), m_id_parent int) 
insert into @v_A_TasksMail values
 (1, 'vova@yandex.ru', 'vasya@mail.ru', 'Поздравляем Вас с Новым Годом!', 'Добрый день! Примите наши теплый поздравления', 'Всеволод Гаврилов', 22)
,(2, 'vova@yandex.ru', 'ivan@mail.ru', 'Поздравляем Вас с Новым Годом!', 'Добрый день! Примите наши теплый поздравления', 'Всеволод Гаврилов', 22) 
,(3, 'vova@yandex.ru', 'petr@mail.ru', 'Поздравляем Вас с Новым Годом!', 'Добрый день! Примите наши теплый поздравления', 'Всеволод Гаврилов', 22) 
,(4, 'gena@yandex.ru', 'masha@mail.ru', 'Услуги клининга в Санкт-Петербурге', 'Добрый день! Заказывайте клининг только у нас!', 'Всеволод Гаврилов', 23) 
,(5, 'gena@yandex.ru', 'dasha@mail.ru', 'Услуги клининга в Санкт-Петербурге', 'Добрый день! Заказывайте клининг только у нас!', 'Всеволод Гаврилов', 23) 
,(6, 'gena@yandex.ru', 'zinaida@mail.ru', 'Услуги клининга в Санкт-Петербурге', 'Добрый день! Заказывайте клининг только у нас!', 'Всеволод Гаврилов', 23) 
,(7, 'olga@yandex.ru', 'stepan@mail.ru', 'Фильтры воды для дома и дачи', 'Добрый день! Заказывайте фильтры воды только у нас!', 'Всеволод Гаврилов', 24) 

declare @tMailTest table (mt_id int, mt_name varchar(100), m_id_parent int) 
insert into @tMailTest values
 (1, 'Тест заголовка письма', 22) 
,(2, 'Тест заголовка письма', 23) 

declare @tMailTestValues table (mtv_id int, mt_id int, mtv_value varchar(100))
insert into @tMailTestValues values
 (1, 1, 'С Новым 2018 Годом!')
,(2, 1, 'Поздравляем от всей души с Новым Годом') 
,(3, 1, 'От всей души поздравляем с Новым Годом')
,(4, 2, 'Профессиональные услуги клининга!') 
,(5, 2, 'Позаботьтесь о чистоте в вашем доме')


;with a1 as 
	(select *, n=row_number()over(partition by m_id_parent order by m_id) from @v_A_TasksMail)
,b1 as
	(select 
			a.*
			,b.m_id_parent
			,n=row_number()over(partition by b.m_id_parent order by a.mtv_id) 
			,m=count(a.mtv_id)over(partition by b.m_id_parent)
	from @tMailTestValues a inner join @tMailTest b on a.mt_id=b.mt_id) 

select 
		new_m_subject	=isnull(b1.mtv_value, a1.m_subject)	
		,a1.* 

from a1 left join b1 on a1.m_id_parent=b1.m_id_parent and (a1.n-1)%b1.m+1=b1.n  


new_m_subjectm_idm_addressFromm_addressTom_subjectm_textm_nameFromm_id_parentn
С Новым 2018 Годом!1vova@yandex.ruvasya@mail.ruПоздравляем Вас с Новым Годом!Добрый день! Примите наши теплый поздравленияВсеволод Гаврилов221
Поздравляем от всей души с Новым Годом2vova@yandex.ruivan@mail.ruПоздравляем Вас с Новым Годом!Добрый день! Примите наши теплый поздравленияВсеволод Гаврилов222
От всей души поздравляем с Новым Годом3vova@yandex.rupetr@mail.ruПоздравляем Вас с Новым Годом!Добрый день! Примите наши теплый поздравленияВсеволод Гаврилов223
Профессиональные услуги клининга!4gena@yandex.rumasha@mail.ruУслуги клининга в Санкт-ПетербургеДобрый день! Заказывайте клининг только у нас!Всеволод Гаврилов231
Позаботьтесь о чистоте в вашем доме5gena@yandex.rudasha@mail.ruУслуги клининга в Санкт-ПетербургеДобрый день! Заказывайте клининг только у нас!Всеволод Гаврилов232
Профессиональные услуги клининга!6gena@yandex.ruzinaida@mail.ruУслуги клининга в Санкт-ПетербургеДобрый день! Заказывайте клининг только у нас!Всеволод Гаврилов233
Фильтры воды для дома и дачи7olga@yandex.rustepan@mail.ruФильтры воды для дома и дачиДобрый день! Заказывайте фильтры воды только у нас!Всеволод Гаврилов241
4 янв 18, 13:33    [21081549]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить