Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Ограничение числа записей / 19 сообщений из 19, страница 1 из 1
26.10.2005, 16:27
    #33345567
Mike Evteev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
ASE 12.5.0.

Ситуевина.
Есть две таблички - юзера и их телефоны. Телефоны имеют признак "предпочтительный" и бывают land and cell.
Нужно показать пользователя и оба его телефона, так чтобы был виден предпочтительный телефон, а если его нет то любой без этого признака.
Без дублирования записей пользователя.

Т.е. нужно отсортировать телефоны по признаку и взять только первый. Пусто если нет ни одного.

Нужно сделать в одном запросе...
Все бы ничего, но ASE моей версии не поддерживает select from select и top.

Да, данные нужно выводить в ASP, так что буду рассматривать любые предложения, вплоть до shaping providers. Но это конечно уже изврат и удар по производительности...
...
Рейтинг: 0 / 0
26.10.2005, 16:36
    #33345615
vooo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
Код: plaintext
1.
set rowcount 
...
Рейтинг: 0 / 0
26.10.2005, 16:56
    #33345693
Mike Evteev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
Где?

Если мне нужно более одного юзера показать, то set rowcount отработает для всего запроса. А мне нужно только телефоны ограничить.

Впрочем, я не упомянул этого..

Еще предложения есть?
...
Рейтинг: 0 / 0
26.10.2005, 17:08
    #33345733
vooo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
А хранимая процедура удовлетворяет условию "в одном запросе"?
...
Рейтинг: 0 / 0
26.10.2005, 17:48
    #33345862
Mike Evteev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
В общем да, но что это меняет?

Мне еще нужно поиск по юзерам. Можно ли в ASE выполнить строку?

Еще раз. Мне нужно что-то вроде

Код: plaintext
1.
2.
3.
4.
5.
6.
select u.user_name, c.number, l.number
   from user u, 
         (select top  1  id, number from phone where type = 'с' order by preferred desc) c,
         (select top  1  id, number from phone where type = 'l' order by preferred desc) l
   where join_conditions and
            search_conditions
...
Рейтинг: 0 / 0
26.10.2005, 18:15
    #33345946
vooo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
В общем да, но что это меняет?
как вариант - написать процедуру в несколько селектов (что безусловно не красиво)
...
Рейтинг: 0 / 0
26.10.2005, 18:20
    #33345956
Mike Evteev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
А можно в двух словах о процедуре?
Я не понимаю как это сделать.

Вот если рассматривать на клиенте, то я бы вычитал юзеров, а потом для каждого из них отдельными запросами телефоны. Это как раз случай где можно использовать set rowcount. И я уже думал о нем.
Но так как юзеров много, то это просто нагнет сервер...

Мне бы одним запросом извернуться...
...
Рейтинг: 0 / 0
26.10.2005, 18:34
    #33346006
vooo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
К сожалению у меня нет сейчас ASE
Но может как то так (воспользоваться аггрегативом min к примеру)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
create table users (id int, name varchar( 50 )) 
go
insert into users values ( 1 ,'A')
insert into users values ( 2 ,'B')
insert into users values ( 3 ,'C')
go

create table phone (id int,phone varchar( 20 ),kind varchar( 1 ))
go
insert into phone values( 1 ,'11','c')
insert into phone values( 1 ,'12','l')
insert into phone values( 1 ,'111','c')
insert into phone values( 1 ,'121','l')

insert into phone values( 2 ,'21','c')
insert into phone values( 2 ,'22','l')
insert into phone values( 3 ,'33','l')


select name,               
isnull((select min(phone) from phone p where p.id=u.id and kind='c'),'n/a') CellPhone,
isnull((select min(phone) from phone p where p.id=u.id and kind='l'),'n/a') LandPhone
from users u
...
Рейтинг: 0 / 0
26.10.2005, 18:45
    #33346049
vooo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
Просто, если бы вы привели полностью структуру таблиц, данные и ожидаемый результат, вам бы помогли быстрее....

А насчет нескольких select в процедуре можно промежуточные результаты записывать в #temp таблицы и осуществлять джойн с их участием .....
например
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
create procedure sp_test 
as
set rowcount  1 
select  id, number 
into #cellphone
from phone where type = 'с' order by preferred desc

select  id, number 
into #landphone
from phone where type = 'l' order by preferred desc

set rowcount  0 
--длаее джойнить users #cellphone #landphone 
go

PS Только я думаю в вашем случае все таки можно сделат в один запрос
...
Рейтинг: 0 / 0
26.10.2005, 18:50
    #33346062
Mike Evteev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
Да, я там с top чушь написал...
Но понятно, что мне нужен один телефон каждого типа для каждого юзера.

так что скорее

Код: plaintext
1.
2.
3.
4.
5.
select  u.user
         (select top  1  number from phone where id = u.id and type = 'c' order by preferred desc) as cell,
         (select top  1  number from phone where id = u.id and type = 'l' order by preferred desc) as land
   from user u
   where search_conditions

Только top не хватает. Может можно хинт какой прямо в select?
...
Рейтинг: 0 / 0
26.10.2005, 21:26
    #33346286
Peter Kirillow
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
table _users
id name
1 user 1
2 user 2

table _phones
id type pref phone
1 c 1223
1 c p 77
1 l p 88
1 l 66
2 c 222

запрос
select
u.name,
coalesce(
(select top 1 p.phone from _phones p where u.id = p.id and type = 'c' and pref='p'),
(select top 1 p.phone from _phones p where u.id = p.id and type = 'c'),
""
) as C,
coalesce(
(select top 1 p.phone from _phones p where u.id = p.id and type = 'l' and pref='p'),
(select top 1 p.phone from _phones p where u.id = p.id and type = 'l'),
""
) as L
from _users u

результат
name C L
user 1 77 88
user 2 222
...
Рейтинг: 0 / 0
26.10.2005, 21:47
    #33346293
Mike Evteev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create table person(
   id integer,
   name varchar( 50 )
)

create table phone(
  person_id integer,
  number char( 8 ),
  is_preferred char( 1 ), --  Y, N
  phone_type integer   -- 1=land, 2=cell
)


Запрос:
Показать всех person удовлетворяющим критериям поиска. Для каждой person вывести два телефона (cell & land). Если среди телефонов есть предпочтительный, то вывести его, если нет то любой из оставшихся данного типа. Если нет ни одного данного типа телефона - пусто. Оба cell и land, могут иметь признак предпочтения.
При этом барин желает искать как по имени, так и реверсно - по номеру телефона. (Ну, блин, как же плохо без select from select...)

В оракле или MS SQL решилось бы с пол-пинка, так как есть возможность взять top 1 в коррелированном запросе.

Я вот решил на все плюнуть и возложить все на хрупкие плечи клиентской части...
Сделать что-то вроде
Код: plaintext
1.
2.
3.
4.
5.
    select u.name, p.number, p.phone_type, p.is_preferred
        from person u, phone p
        where u.id = p.person_id
           [(and name = 'something')|(and p._number = 'something' )]
        order by u.id, p.phone_type, p.is_preferred

А потом просто бежать по результату и сворачивать записи. Если телефон найден, то остальные записи просто прорускаются, пока не найдена новая персона. Если кто и будет ждать, так это web клиент. Но хоть сервер базы, не буду загружать дурной работой...
...
Рейтинг: 0 / 0
26.10.2005, 22:16
    #33346307
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
Два подзапроса в isnull сделайте, и будет вам счастье.
Типа
isnull( (select xxx from phones where такой телефон),
(select xxx from phones where разэтакий телефон) )
...
Рейтинг: 0 / 0
26.10.2005, 23:55
    #33346368
Mike Evteev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
Peter Kirillow
Ну нетути top у него. 12.5.0
...
Рейтинг: 0 / 0
27.10.2005, 00:00
    #33346371
Mike Evteev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
MasterZivДва подзапроса в isnull сделайте, и будет вам счастье.
Типа
isnull( (select xxx from phones where такой телефон),
(select xxx from phones where разэтакий телефон) )

У меня телефонов разэтаких может быть больше одного...
Очень сомневаюсь что isnull прокатит ;-)

ASE 12.5.0
...
Рейтинг: 0 / 0
27.10.2005, 10:39
    #33346804
vooo
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
Есть способ - вроде работает
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
create table users (id int, name varchar( 50 )) 
go
insert into users values ( 1 ,'A')
insert into users values ( 2 ,'B')
insert into users values ( 3 ,'C')
go
create table phone (id int,phone varchar( 20 ),kind varchar( 1 ),prereffered int )
go
insert into phone values( 1 ,'1100000000000','c', 1 )
insert into phone values( 1 ,'12','l', 1 )
insert into phone values( 1 ,'111','c', 2 )
insert into phone values( 1 ,'121','l', 2 )
insert into phone values( 1 ,'------','c', 0 )

insert into phone values( 2 ,'21','c', 21 )
insert into phone values( 2 ,'22','c', 11 )
insert into phone values( 2 ,'00','c', 5 )
insert into phone values( 3 ,'33','l', 20 )
go
select name,               
isnull((select phone from phone p where p.id=u.id and p.kind='c' and  (select count(*) from phone p2 where p2.id=p.id and p.kind=p2.kind and p.prereffered>=p2.prereffered)= 1 ),'n/a') CellPhone,
isnull((select phone from phone p where p.id=u.id and p.kind='l' and  (select count(*) from phone p2 where p2.id=p.id and p.kind=p2.kind and p.prereffered>=p2.prereffered)= 1 ),'n/a') LandPhone
from users u
...
Рейтинг: 0 / 0
27.10.2005, 20:26
    #33348721
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
isnull прокатит. Если много телефонов, то вам придется выделить как-то один и его показывать. В SQL нет операции "взять любую запить".
...
Рейтинг: 0 / 0
27.10.2005, 21:40
    #33348780
Mike Evteev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
Ok!
Всем спасибо! Буду доводить идею до ума.
...
Рейтинг: 0 / 0
27.10.2005, 23:12
    #33348875
Zhora
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Ограничение числа записей
MasterZivisnull прокатит. Если много телефонов, то вам придется выделить как-то один и его показывать. В SQL нет операции "взять любую запить".

Ну, может тогда так:
select u.name,
isnull(max(case when p1.kind = 'c' then p1.phone else null end),'n/a') CellPhone,
isnull(max(case when p1.kind = 'l' then p1.phone else null end),'n/a') Landphone
from phone p1, users u
where p1.id = u.id
and p1.prereffered = (select min(p2.prereffered)
from phone p2
where p2.id = p1.id
and p2.kind = p1.kind
group by p2.id, p2.kind)
group by u.name
go
...
Рейтинг: 0 / 0
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Ограничение числа записей / 19 сообщений из 19, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]