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

Откуда: Moscow city
Сообщений: 616
здравствуйте всезнающие алл
имею вот такую форму запроса
    SELECT CASE 
	           WHEN     (EXISTS(SELECT 1 FROM table_b b WHERE  b.id = a.id AND b.id IN ('R', 'L', 'V', 'C')))
	            AND (NOT EXISTS(SELECT 1 FROM table_b b WHERE  b.id = a.id AND b.id IN ('S', 'W', 'O', 'D'))) THEN 'R'
	           WHEN (NOT EXISTS(SELECT 1 FROM table_b b WHERE  b.id = a.id AND b.id IN ('R', 'L', 'V', 'C')))
                    AND     (EXISTS(SELECT 1 FROM table_b b WHERE  b.id = a.id AND b.id IN ('S', 'W', 'O', 'D'))) THEN 'D'
	           WHEN     (EXISTS(SELECT 1 FROM table_b b WHERE  b.id = a.id AND b.id IN ('R', 'L', 'V', 'C')))	                 
	            AND     (EXISTS(SELECT 1 FROM table_b b WHERE  b.id = a.id AND b.id IN ('S', 'W', 'O', 'D'))) THEN 'M'
	           ELSE 'N'
	           END
    FROM table_a a
    WHERE a.id = @id


но думается мне, что можно как-то упростить, но как, пока не возьму в толк.
принцип весь в том, что таблица table_a имеет уникальные записи по id, а соответственно table_b множественные к таблице table_a.

помогите, пожалуйста.
спасибо


в диктанте три-четыре варнинга, но в общем компилируется
31 июл 13, 11:07    [14641568]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
Glory
Member

Откуда:
Сообщений: 104760
Сделать 1 раз JOIN
А в case оставить проверку значений
31 июл 13, 11:13    [14641606]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
SHKoder
Member

Откуда: Moscow city
Сообщений: 616
Glory
Сделать 1 раз JOIN
А в case оставить проверку значений

боюсь что нет, так не выйдет.
одним джоином я не смогу проверить наличие одной группы признаков и отсутствие другой группы. либо вхождение обеих групп одновременно.
31 июл 13, 11:18    [14641627]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
Glory
Member

Откуда:
Сообщений: 104760
SHKoder
одним джоином я не смогу проверить наличие одной группы признаков и отсутствие другой группы. либо вхождение обеих групп одновременно.

Можете. Для этого нужна группировка и агрегатная функция с фильтрацией
31 июл 13, 11:20    [14641639]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
SHKoder
Member

Откуда: Moscow city
Сообщений: 616
в том то и цинус, что одна группа признаков отвечает за один статус, а другая группа за другой.
если признаки в рамках (наборе) одной группы и точно не в другой, то сущность в одном статусе, если на оборот, то в другом, а если и в том и в другом, то в третьем. либо ни в каком.
31 июл 13, 11:22    [14641648]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
SHKoder
Member

Откуда: Moscow city
Сообщений: 616
Glory
SHKoder
одним джоином я не смогу проверить наличие одной группы признаков и отсутствие другой группы. либо вхождение обеих групп одновременно.

Можете. Для этого нужна группировка и агрегатная функция с фильтрацией


спасибо, научите, пожалуйста, что такое агрегатная функция с фильтрацией?

под рукой имею MS SQL 2008 R2
31 июл 13, 11:23    [14641652]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
Glory
Member

Откуда:
Сообщений: 104760
SHKoder
если признаки в рамках (наборе) одной группы и точно не в другой, то сущность в одном статусе, если на оборот, то в другом, а если и в том и в другом, то в третьем. либо ни в каком.

И что мешает посчитать количество для IN ('S', 'W', 'O', 'D') и IN ('S', 'W', 'O', 'D') и сравнить их 0 ?
31 июл 13, 11:25    [14641670]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
Glory
Member

Откуда:
Сообщений: 104760
SHKoder
спасибо, научите, пожалуйста, что такое агрегатная функция с фильтрацией?

под рукой имею MS SQL 2008 R2

Фильтрация агрегатов всю жизнь делалась через HAVING
Или помещением case внутрь агрегата

Сообщение было отредактировано: 31 июл 13, 11:27
31 июл 13, 11:26    [14641679]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
SHKoder
Member

Откуда: Moscow city
Сообщений: 616
Glory
SHKoder
если признаки в рамках (наборе) одной группы и точно не в другой, то сущность в одном статусе, если на оборот, то в другом, а если и в том и в другом, то в третьем. либо ни в каком.

И что мешает посчитать количество для IN ('R', 'L', 'V', 'C') и IN ('S', 'W', 'O', 'D') и сравнить их 0 ?

ась?
31 июл 13, 11:27    [14641688]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
Glory
Member

Откуда:
Сообщений: 104760
SHKoder
Glory
пропущено...

И что мешает посчитать количество для IN ('R', 'L', 'V', 'C') и IN ('S', 'W', 'O', 'D') и сравнить их 0 ?

ась?

Офигеть просто
SUM (...IN ('R', 'L', 'V', 'C') ) и SUM( IN ('S', 'W', 'O', 'D') ) дадут 2 суммы
Сранение которых с 0-ем дает 4 возможные комбинации
31 июл 13, 11:30    [14641713]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
SELECT CASE WHEN t1.id IS NULL THEN CASE WHEN t2.id IS NULL THEN 'N' ELSE 'D' END ELSE CASE WHEN t2.id IS NULL THEN 'R' ELSE 'M' END END
FROM table_a a
OUTER APPLY(SELECT TOP(1) 1 FROM table_b b WHERE b.id = a.id AND b.id IN ('R', 'L', 'V', 'C')) t1(id)
OUTER APPLY(SELECT TOP(1) 1 FROM table_b b WHERE b.id = a.id AND b.id IN ('S', 'W', 'O', 'D')) t2(id)
WHERE a.id = @id;
31 июл 13, 11:32    [14641726]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
SHKoder
Member

Откуда: Moscow city
Сообщений: 616
Glory
Офигеть просто
SUM (...IN ('R', 'L', 'V', 'C') ) и SUM( IN ('S', 'W', 'O', 'D') ) дадут 2 суммы
Сранение которых с 0-ем дает 4 возможные комбинации

не нужно фигеть, я в деталях понимаю о чем речь, и HAVING знаю, и как агрегат использую. и кейс в него вставить не проблема, не очень только понимаю как суммы посчитать для групп
31 июл 13, 11:34    [14641754]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
Glory
Member

Откуда:
Сообщений: 104760
SHKoder
не очень только понимаю как суммы посчитать для групп

В двух отдельных столбцах
31 июл 13, 11:38    [14641782]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
а вот это условие разве вообще когда нибудь выполнится?
WHEN     (EXISTS(SELECT 1 FROM table_b b WHERE  b.id = a.id AND b.id IN ('R', 'L', 'V', 'C')))	                 
	            AND     (EXISTS(SELECT 1 FROM table_b b WHERE  b.id = a.id AND b.id IN ('S', 'W', 'O', 'D'))) THEN 'M'
31 июл 13, 11:42    [14641806]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
SHKoder
Member

Откуда: Moscow city
Сообщений: 616
Мистер Хенки
а вот это условие разве вообще когда нибудь выполнится?
WHEN     (EXISTS(SELECT 1 FROM table_b b WHERE  b.id = a.id AND b.id IN ('R', 'L', 'V', 'C')))	                 
	            AND     (EXISTS(SELECT 1 FROM table_b b WHERE  b.id = a.id AND b.id IN ('S', 'W', 'O', 'D'))) THEN 'M'

выполнится, в случае
with cte (id, type) as (
select 1, 'R' union all
select 1, 'L' union all
select 1, 'V' union all
select 1, 'C' union all
select 1, 'S' union all
select 1, 'W' union all
select 1, 'O' union all
select 1, 'D'
)
select * from cte

я прошу прощения, допустил опечатку при адаптации скрипта с рабой БД в форум.
31 июл 13, 11:54    [14641919]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
SHKoder
Member

Откуда: Moscow city
Сообщений: 616
*с рабочей БД в форум
31 июл 13, 11:55    [14641929]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
SHKoder
Member

Откуда: Moscow city
Сообщений: 616
Glory
SHKoder
пропущено...

ась?

Офигеть просто
SUM (...IN ('R', 'L', 'V', 'C') ) и SUM( IN ('S', 'W', 'O', 'D') ) дадут 2 суммы
Сранение которых с 0-ем дает 4 возможные комбинации


Нет, я таки не понял о чем речь.
одним джоином, агрегировать в SUM и притом HAVING фильтровать через CASE.

пожалуйста, дайте пример... буду научаться

спасибо
31 июл 13, 12:00    [14641968]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
Glory
Member

Откуда:
Сообщений: 104760
SUM (CASE ...IN ('R', 'L', 'V', 'C') THEN 1 ELSE 0 END) as col1, SUM(CASE ... IN ('S', 'W', 'O', 'D' THEN 1 ELSE 0 END) as col2
...
CASE when col1 > 0 AND col2 > 0 THEN '11'
when col1 = 0 AND col2 > 0 THEN '01'
when col1 = 0 AND col2 = 0 THEN '00'
when col1 > 0 AND col2 = 0 THEN '10'
END
элементарная двоичная логика
31 июл 13, 12:05    [14642002]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
select SUBSTRING('NDRM', R+S, 1)
from (
   select 
      R=case when exists(select * from table_a where id IN ('R', 'L', 'V', 'C')) then 1 else 0 end,
      S=case when exists(select * from table_a where id IN ('S', 'W', 'O', 'D')) then 4 else 2 end
   ) c
31 июл 13, 12:15    [14642096]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
не, наврал :)
31 июл 13, 12:17    [14642111]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
SHKoder
Member

Откуда: Moscow city
Сообщений: 616
Glory
...
элементарная двоичная логика

у меня получилось следующее

SELECT 
a.id, 
CASE when p.col1 > 0 AND p.col2 > 0 THEN 'S'
	 when p.col1 = 0 AND p.col2 > 0 THEN 'D'
	 when p.col1 = 0 AND p.col2 = 0 THEN 'N'
	 when p.col1 > 0 AND p.col2 = 0 THEN 'R'
end as rstp_id
FROM table_a a
left join (select 
pr.id,
SUM(CASE WHEN pr.type IN ('R', 'L', 'V', 'C') THEN 1 ELSE 0 END) as col1,
SUM(CASE WHEN pr.type IN ('S', 'W', 'O', 'D') THEN 1 ELSE 0 END) as col2
from table_b  pr 
group by pr.id) p
on p.id = a.id


а где же мне тут нужен HAVING ??
31 июл 13, 12:20    [14642129]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
вот так :)
select SUBSTRING('NDRM', R+S ,1)
from table_a a
cross apply (select 
   R=case when exists(select * from table_a where id=@id and @id IN ('R', 'L', 'V', 'C')) then 1 else 0 end,
   S=case when exists(select * from table_a where id=@id and @id IN ('S', 'W', 'O', 'D')) then 2 else 0 end
   ) c
31 июл 13, 12:21    [14642138]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
ну елы-палы) снова наврал...
нафик...
31 июл 13, 12:22    [14642147]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
select SUBSTRING('NDRM', R+S ,1)
from (
   select 
      R=case when exists(select * from table_a where id=@id and @id IN ('R', 'L', 'V', 'C')) then 1 else 0 end,
      S=case when exists(select * from table_a where id=@id and @id IN ('S', 'W', 'O', 'D')) then 2 else 0 end
   ) c
31 июл 13, 12:23    [14642153]     Ответить | Цитировать Сообщить модератору
 Re: ветка не нравится мне  [new]
Glory
Member

Откуда:
Сообщений: 104760
SHKoder
а где же мне тут нужен HAVING ??

Вам нужен не HAVING, а внимательность при чтении ответов. Союзы ИЛИ/И имеют разное значение
"Фильтрация агрегатов всю жизнь делалась через HAVING. Или помещением case внутрь агрегата "
31 июл 13, 12:24    [14642157]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить