Модераторы: Akina

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Словарь на основе одной таблицы. 
V
    Опции темы
alexburzak
  Дата 5.11.2007, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 12.3.2007
Где: Hadera

Репутация: нет
Всего: 1



MS SQL Server.
Задача: делаю словарь, допустим перевод с английского на русский. 
Таблица элементарная. Два поля скажем EngWord и RusWord.
Написал вот так:
SELECT EngWord, RusWord
FROM DictionaryEngToRus
WHERE EngWord IN ('case', 'cases', 'werr', 'accessories') 
При этом слово 'werr' не существует(нет на него перевода).
В результате получаю таблицу из трех строк,а хочется из четерех.
Что бы на слове 'werr' было написанно к пример «NULL»  smile 
Как я могу отобразить также и те поля в которых нет перевода?

PM   Вверх
Servena
Дата 5.11.2007, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 24.7.2007
Где: Днепропетровск

Репутация: 10
Всего: 14



Тут одним запросом не обойтись. 
Лучше это делать пакетом. Я думаю, можно так: каждое слово определять в отдельном запросе Селект и помещать во временную таблицу, а когда будет пусто (определять с помощью @@ROWCOUNT) заносить в таблицу то слово или выражение, которое показывает, что такого слова нет.

А вообще, лучше с БД общаться на уровне одного Селекта, а в программе определять, вернуло оно что-то или нет.
PM MAIL   Вверх
Akina
Дата 5.11.2007, 23:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 25
Всего: 454



То, что вы хотите получить в конечной выборке, ОТСУТСТВУЕТ в исходных данных.
Решение задачи невозможно без помещения набора проверяемых полей во временную таблицу либо без использования их в запросе в литеральной форме
Мне представляется более разумным помещение проверяемого набора во временную таблицу. Тогда можно использовать соответствующий JOIN.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
alexburzak
  Дата 6.11.2007, 09:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 12.3.2007
Где: Hadera

Репутация: нет
Всего: 1



Цитата(Servena @ 5.11.2007,  20:30)
А вообще, лучше с БД общаться на уровне одного Селекта, а в программе определять, вернуло оно что-то или нет.

Ну наверное это самое простое решение. Возможно так и сделаю. . . smile

Добавлено через 1 минуту и 36 секунд
Цитата(Akina @ 5.11.2007,  23:23)
Мне представляется более разумным помещение проверяемого набора во временную таблицу. Тогда можно использовать соответствующий JOIN.

Интересное решение.  smile 
Для общего развития попробую сделать. Спасибо.
PM   Вверх
Servena
Дата 6.11.2007, 09:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 24.7.2007
Где: Днепропетровск

Репутация: 10
Всего: 14



Не забудь про @@ROWCOUNT - им можно определить вернул ли Селект что-нибудь, и тогда используй соединение (думаю UNION подойдет больше всего для этой цели) чтобы добавить к результирующей таблице либо перевод, либо то слово, которое будет означать что нет перевода.
PM MAIL   Вверх
Akina
Дата 6.11.2007, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 25
Всего: 454



Цитата(alexburzak @  6.11.2007,  10:32 Найти цитируемый пост)
наверное это самое простое решение. Возможно так и сделаю

Метод хорош, если таблица невелика. Но если этот "один селект" вывалит на клиента десяток тысяч записей - будет тебе щастье...



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Servena
Дата 6.11.2007, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 24.7.2007
Где: Днепропетровск

Репутация: 10
Всего: 14



Один Селект, имеется ввиду - выбирать одно слово.
Сколько слов - столько и Селектов соединенных между собой Юнионом. 
Получится результат столбик, в котором будет или перевод или например: "нет перевода".
PM MAIL   Вверх
alexburzak
  Дата 6.11.2007, 10:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 12.3.2007
Где: Hadera

Репутация: нет
Всего: 1



Цитата(Akina @ 6.11.2007,  09:47)
Цитата(alexburzak @  6.11.2007,  10:32 Найти цитируемый пост)
наверное это самое простое решение. Возможно так и сделаю

Метод хорош, если таблица невелика. Но если этот "один селект" вывалит на клиента десяток тысяч записей - будет тебе щастье...

Да ты(Вы) прав, буду думать.

Добавлено через 2 минуты
Цитата(Servena @ 6.11.2007,  09:51)
Один Селект, имеется ввиду - выбирать одно слово.
Сколько слов - столько и Селектов соединенных между собой Юнионом. 
Получится результат столбик, в котором будет или перевод или например: "нет перевода".

Тогда  smile 
PM   Вверх
Servena
Дата 6.11.2007, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 24.7.2007
Где: Днепропетровск

Репутация: 10
Всего: 14



Вариант первый (назовем его программным):
Код

SELECT EngWord, RusWord
FROM DictionaryEngToRus
WHERE EngWord IN ('case') 

Одно слово в запросе - а сколько нужно перевести слов - столько и таких запросов. А в языке программирования уже определять: если запрос вернул значение - значит перевод есть, если не вернул - значит перевода нет(т.е., если тебе нужно перевести сразу три слова - то делаешь это в цикле 3 раза по одному слову).

(как для меня - наиболее правильный вариант решения данной задачи).
PM MAIL   Вверх
Servena
Дата 6.11.2007, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 24.7.2007
Где: Днепропетровск

Репутация: 10
Всего: 14



Сейчас в Northwindе что-нибудь найду в качестве примера.
PM MAIL   Вверх
Servena
Дата 6.11.2007, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 24.7.2007
Где: Днепропетровск

Репутация: 10
Всего: 14



Второй вариант (назовем его датабазным):
Использую БД Northwind, таблицу Employees, а в ней колонку LastName.
Код

DECLARE @tempTable TABLE(translate VARCHAR(30))
SELECT translate FROM @tempTable
UNION ALL
SELECT LastName FROM Employees WHERE LastName LIKE 'Davolio'
UNION ALL
SELECT LastName FROM Employees WHERE LastName LIKE 'Вася'
UNION ALL
SELECT LastName FROM Employees WHERE LastName LIKE 'Suyama'

Имени "Вася" в этой таблице нет, поэтому там ничего не возвращает пока.
Это как использовать Юнион, сейчас подумаю, как сюда приделать @@ROWCOUNT.
PM MAIL   Вверх
alexburzak
  Дата 6.11.2007, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 12.3.2007
Где: Hadera

Репутация: нет
Всего: 1



Цитата(Servena @ 6.11.2007,  10:38)
Вариант первый (назовем его программным):
Код

SELECT EngWord, RusWord
FROM DictionaryEngToRus
WHERE EngWord IN ('case') 

Одно слово в запросе - а сколько нужно перевести слов - столько и таких запросов. А в языке программирования уже определять: если запрос вернул значение - значит перевод есть, если не вернул - значит перевода нет(т.е., если тебе нужно перевести сразу три слова - то делаешь это в цикле 3 раза по одному слову).

(как для меня - наиболее правильный вариант решения данной задачи).

Спасибо но этот вариант я и без форума знал, а хочется продвигатся в своей квалификации...  smile 
PM   Вверх
Servena
Дата 6.11.2007, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 24.7.2007
Где: Днепропетровск

Репутация: 10
Всего: 14



Вот, так еще проще:
Код

DECLARE @tempTable TABLE(translate VARCHAR(30))
DECLARE @tempString VARCHAR(30)

INSERT INTO @tempTable SELECT LastName FROM Employees WHERE LastName LIKE 'Davolio'
IF @@ROWCOUNT=0 INSERT INTO @tempTable SELECT 'Нет такого слова'

INSERT INTO @tempTable SELECT LastName FROM Employees WHERE LastName LIKE 'Вася'
IF @@ROWCOUNT=0 INSERT INTO @tempTable SELECT 'Нет такого слова'

INSERT INTO @tempTable SELECT LastName FROM Employees WHERE LastName LIKE 'Suyama'
IF @@ROWCOUNT=0 INSERT INTO @tempTable SELECT 'Нет такого слова'

SELECT translate FROM @tempTable

Попробуй запусти на БД Northwind.
PM MAIL   Вверх
VOS
Дата 6.11.2007, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 31.1.2007

Репутация: 2
Всего: 8



Можно еще так:

DECLARE @tempTable TABLE(eng varchar(40))

insert into @temptable (eng) values('case')
insert into @temptable (eng) values('cases')
insert into @temptable (eng) values('werr')


SELECT  RusWord,eng FROM @temptable left outer  join DictionaryEngToRus on (eng= EngWord )


Вместо этого:

DECLARE @tempTable TABLE(eng varchar(40))
insert into @temptable (eng) values('case')
insert into @temptable (eng) values('cases')
insert into @temptable (eng) values('werr')

можно состряпать функцию, куда передавать строку (в ней слова с разделителями), а она возвращает набор данных.
PM MAIL   Вверх
Servena
Дата 6.11.2007, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 251
Регистрация: 24.7.2007
Где: Днепропетровск

Репутация: 10
Всего: 14



Да, вариант с левым соединением - лучше.
Поскольку он предусматривает вариант, когда на одно английское слово может быть (а оно так и будет) несколько русских.

Добавлено через 6 минут и 47 секунд
Вот мой вариант, который учитывает вариант когда на одно английское слово - не одно русское.
Код

DECLARE @tempTable TABLE(translateEng VARCHAR(30),translateRus VARCHAR(30))

INSERT INTO @tempTable SELECT LastName,FirstName FROM Employees WHERE LastName LIKE 'Davolio'
IF @@ROWCOUNT=0 INSERT INTO @tempTable SELECT 'Нет такого слова','Нет такого слова'

INSERT INTO @tempTable SELECT LastName,FirstName FROM Employees WHERE LastName LIKE 'Вася'
IF @@ROWCOUNT=0 INSERT INTO @tempTable SELECT 'Нет такого слова','Нет такого слова'

INSERT INTO @tempTable SELECT LastName,FirstName FROM Employees WHERE LastName LIKE 'Suyama'
IF @@ROWCOUNT=0 INSERT INTO @tempTable SELECT 'Нет такого слова','Нет такого слова'

SELECT translateEng,translateRus FROM @tempTable

на БД Northwind
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "MS SQL"
Akina

Akina

Запрещается!

Публиковать ссылки и обсуждать взлом чего бы то ни было.

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы составления неспецифических запросов рассматриваются здесь
  • Используйте теги [code=sql][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Zloxa, Akina.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MS SQL Server | Следующая тема »


 




[ Время генерации скрипта: 0.0746 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.