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

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

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

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

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

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

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

Еще предложения есть?
...
Рейтинг: 0 / 0
Ограничение числа записей
    #33345733
vooo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А хранимая процедура удовлетворяет условию "в одном запросе"?
...
Рейтинг: 0 / 0
Ограничение числа записей
    #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
Ограничение числа записей
    #33345946
vooo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем да, но что это меняет?
как вариант - написать процедуру в несколько селектов (что безусловно не красиво)
...
Рейтинг: 0 / 0
Ограничение числа записей
    #33345956
Mike Evteev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А можно в двух словах о процедуре?
Я не понимаю как это сделать.

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

Мне бы одним запросом извернуться...
...
Рейтинг: 0 / 0
Ограничение числа записей
    #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
Ограничение числа записей
    #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
Ограничение числа записей
    #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
Ограничение числа записей
    #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
Ограничение числа записей
    #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
Ограничение числа записей
    #33346307
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Два подзапроса в isnull сделайте, и будет вам счастье.
Типа
isnull( (select xxx from phones where такой телефон),
(select xxx from phones where разэтакий телефон) )
...
Рейтинг: 0 / 0
Ограничение числа записей
    #33346368
Mike Evteev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Peter Kirillow
Ну нетути top у него. 12.5.0
...
Рейтинг: 0 / 0
Ограничение числа записей
    #33346371
Mike Evteev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivДва подзапроса в isnull сделайте, и будет вам счастье.
Типа
isnull( (select xxx from phones where такой телефон),
(select xxx from phones where разэтакий телефон) )

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

ASE 12.5.0
...
Рейтинг: 0 / 0
Ограничение числа записей
    #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
Ограничение числа записей
    #33348721
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
isnull прокатит. Если много телефонов, то вам придется выделить как-то один и его показывать. В SQL нет операции "взять любую запить".
...
Рейтинг: 0 / 0
Ограничение числа записей
    #33348780
Mike Evteev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ok!
Всем спасибо! Буду доводить идею до ума.
...
Рейтинг: 0 / 0
Ограничение числа записей
    #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
19 сообщений из 19, страница 1 из 1
Форумы / Sybase ASA, ASE, IQ [игнор отключен] [закрыт для гостей] / Ограничение числа записей
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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