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

Откуда:
Сообщений: 266
Добрый день.

Есть таблица:

id                     name                      about
1               ООО Фирма 1                          text
2               ИП "Хмельницкий"                    text
3               ООО "Евроокна"                       text
4               ООО "Двери" $1                       text
5               ООО "Юр услуги" $2                 text
6               ООО Фирма $3                        text


и запрос на поиск по about

SELECT * FROM  table WHERE about = 'text'


Подскажите как сделать так, чтобы результаты запроса сначала выводились в порядке очередности после $(если таковые имеются), а затем в порядке возрастания по имени фирмы.
Т.е., чтобы сначала результаты выводились по фирмам ООО "Двери" $1, ООО "Юр услуги" $2, ООО Фирма $3, а затем по всем остальным фирмам.

P.S.: желательно одним запросом..
22 мар 13, 08:47    [14080049]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать сортировку?  [new]
Dima T
Member

Откуда:
Сообщений: 15858
У тебя структура нездоровая, остюда все проблемы. Как понимаю $1, $2 это что-то типа порядка вывода. Вынеси его в отдельное поле. Например nOrder и проставь всем. Сделай по умолчанию 99999. Поле лучше числовое, а не символьное.
Тогда легко выбирать будет
SELECT * FROM  table WHERE about = 'text' order by nOrder
22 мар 13, 09:26    [14080190]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать сортировку?  [new]
Amateur7
Member

Откуда:
Сообщений: 266
Dima T,

там вся база нездоровая, но изменить не могу, иначе все было очень легко.
22 мар 13, 09:47    [14080264]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать сортировку?  [new]
aleks2
Guest
SELECT * FROM  table WHERE about = 'text'
order by case when charindex(name, '$')>0 then cast(substring(name, charindex(name, '$')+1, 10) as int) else 99999 end, name
22 мар 13, 10:01    [14080330]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать сортировку?  [new]
ambarka_max
Member

Откуда: Россия
Сообщений: 517
aleks2
SELECT * FROM  table WHERE about = 'text'
order by case when charindex(name, '$')>0 then cast(substring(name, charindex(name, '$')+1, 10) as int) else 99999 end, name

cast( as int) - ага, не прокатит
22 мар 13, 14:50    [14082741]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать сортировку?  [new]
Amateur7
Member

Откуда:
Сообщений: 266
подсказали такое решение:

SELECT *
FROM table
WHERE about = 'text'
ORDER  BY CASE WHEN name LIKE '%$..' THEN 0 ELSE 1 END,
          name
22 мар 13, 17:27    [14083786]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать сортировку?  [new]
Amateur7
Member

Откуда:
Сообщений: 266
теперь интереснее

как добавить такую же сортировку в пример запроса ниже:

;
WITH ranked AS (
  SELECT
    p.id_price as p_id_price, 
    p.id_service as p_id_service, 
    p.name as p_name, 
    p.name_original as p_name_original, 
    p.id_producer_country as p_id_producer_country, 
    p.id_firm as p_id_firm, 
    f.name as f_name, 
    f.address as f_address, 
    f.phone as f_phone, 
    city.name as city_name, 
    pc.name as pc_name,
    ROW_NUMBER() OVER (
      PARTITION BY p.id_firm
      ORDER BY
        CASE  -- this criterion puts matching products before non-matching ones
          WHEN $spname COLLATE SQL_Latin1_General_Cp1251_CI_AS
          THEN 1 ELSE 2
        END,
        p.id_price  -- you may use any sorting criteria at this point,
                    -- just ensure it makes the results predictable
    ) AS rnk
  FROM Price p 
  left join Firm f 
    on f.id_service=p.id_service 
    AND f.id_city=p.id_city 
    AND f.id_firm=p.id_firm 
  left join City city 
    on city.id_city = p.id_city 
  left join Producer_country pc 
    on pc.id_producer_country = p.id_producer_country 
  WHERE p.id_city='73041' 
    AND p.include='1' 
    AND p.blocked='0' 
    AND f.blocked='0' 
    AND ( $sfname COLLATE SQL_Latin1_General_Cp1251_CI_AS
       OR $spname COLLATE SQL_Latin1_General_Cp1251_CI_AS )
)
SELECT p.name
FROM ranked
WHERE rnk = 1
;
22 мар 13, 17:29    [14083798]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать сортировку?  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Amateur7
подсказали такое решение:

SELECT *
FROM table
WHERE about = 'text'
ORDER  BY CASE WHEN name LIKE '%$..' THEN 0 ELSE 1 END,
          name

И как это решение согласуется с условием "чтобы результаты запроса сначала выводились в порядке очередности после $(если таковые имеются)"?
22 мар 13, 17:57    [14083947]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать сортировку?  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 34706
Amateur7,

1нф, искать в нете и читать до просветления...
22 мар 13, 18:10    [14084001]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать сортировку?  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
Вот вариант решения :)
;with myTable as (select * from (values
   (1,'ООО Фирма 1','text'),
   (2,'ИП "Хмельницкий"','text'),
   (3,'ООО "Евроокна"','text'),
   (4,'ООО "Двери" $1','text'),
   (5,'ООО "Юр услуги" $2','text'),
   (6,'ООО Фирма $3','text')
   )t(id,name,about))
select t.* 
from myTable t
cross apply (select 
   ord=RIGHT(name,LEN(name)-charindex('$',name)),
   iord=1-SIGN(charindex('$',name)) ) c
where about='text'
order by iord,ord
PS основано на том, что $ в конце поля и числа однозначные. Если после $ автоматом добавляется порядковый номер, после которого ничего нет - тоже существенное упрощение задачи, тогда ord=convert(int, ...).
22 мар 13, 18:30    [14084079]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать сортировку?  [new]
Amateur7
Member

Откуда:
Сообщений: 266
Гость333,

пример http://sqlfiddle.com/#!3/d1514/5
22 мар 13, 18:36    [14084097]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать сортировку?  [new]
Amateur7
Member

Откуда:
Сообщений: 266
Cygapb-007,

нужно чтобы все условия по первоначальному запросу также соблюдались..
22 мар 13, 18:39    [14084112]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать сортировку?  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
Amateur7, а что не так-то??
22 мар 13, 18:45    [14084142]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать сортировку?  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
Ну, про многозначные числа приврал малость... :)
22 мар 13, 18:50    [14084161]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать сортировку?  [new]
Гость333
Member

Откуда:
Сообщений: 3683
Amateur7
Гость333,

пример http://sqlfiddle.com/#!3/d1514/5

Ок, а теперь добавьте в итоговые столбцы — "CASE WHEN name LIKE '%$..' THEN 0 ELSE 1 END" — и убедитесь, что для вашего примера это выражение везде равно 1.
22 мар 13, 19:06    [14084210]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать сортировку?  [new]
Amateur7
Member

Откуда:
Сообщений: 266
получился такой вот запрос:
;
WITH ranked AS (
  SELECT
    p.id_price as p_id_price, 
    p.id_service as p_id_service, 
    p.name as p_name, 
    p.name_original as p_name_original, 
    p.id_producer_country as p_id_producer_country, 
    p.id_firm as p_id_firm, 
    f.name as f_name, 
    f.address as f_address, 
    f.phone as f_phone, 
    city.name as city_name, 
    pc.name as pc_name,
    ROW_NUMBER() OVER (
      PARTITION BY p.id_firm
      ORDER BY
        CASE  -- this criterion puts matching products before non-matching ones
          WHEN $spname COLLATE SQL_Latin1_General_Cp1251_CI_AS
          THEN 1 ELSE 2
        END,
        p.id_price  -- you may use any sorting criteria at this point,
                    -- just ensure it makes the results predictable
    ) AS rnk
  FROM Price p 
  left join Firm f 
    on f.id_service=p.id_service 
    AND f.id_city=p.id_city 
    AND f.id_firm=p.id_firm 
  left join City city 
    on city.id_city = p.id_city 
  left join Producer_country pc 
    on pc.id_producer_country = p.id_producer_country 
  WHERE p.id_city='73041' 
    AND p.include='1' 
    AND p.blocked='0' 
    AND f.blocked='0' 
    AND ( $sfname COLLATE SQL_Latin1_General_Cp1251_CI_AS
       OR $spname COLLATE SQL_Latin1_General_Cp1251_CI_AS ) 
)
SELECT TOP $num
  p_id_price, 
  p_id_service, 
  p_name, 
  p_name_original, 
  p_id_producer_country, 
  p_id_firm, 
  f_name, 
  f_address, 
  f_phone, 
  city_name, 
  pc_name
FROM ranked
WHERE rnk = 1
-- the absence of ORDER BY makes your TOP $num results indeterminate
ORDER BY CASE WHEN f_name LIKE '%$%' THEN 0 ELSE 1 END, 
SUBSTRING (f_name ,CHARINDEX('$' , f_name)+1, (LEN(f_name)) - CHARINDEX('$', f_name)) ASC
;
24 мар 13, 15:41    [14089062]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить