[НОВЫЙ ВОПРОС] Помогите упростить SQL запрос

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

[НОВЫЙ ВОПРОС] Помогите упростить SQL запрос

Сообщение java73 » 21.07.2015 15:39:11

Добрый день.
Путём долгих мучений сочинил следующий SQL-запрос:
Код: Выделить всё
USE investpatents;
SELECT trademarks.ID http://freepascal.ru/forum/viewtopic.php?f=26&t=10413as tmID, IsJurholder, HolderID, Number,
jurlica.ID, Shortname
FROM trademarks, jurlica
WHERE trademarks.ID IN (1,2,3,4) AND IsJurholder=TRUE
AND HolderID=jurlica.ID
UNION
SELECT trademarks.ID as tmID, IsJurholder, HolderID, Number,
fizlica.ID, CONCAT(fizlica.Familia,' ',LEFT(fizlica.Name,1),'.',LEFT(fizlica.Otchestvo,1),'.') as Shortname 
FROM trademarks, fizlica
WHERE trademarks.ID IN (1,2,3,4) AND IsJurholder=FALSE
AND HolderID=fizlica.ID;


Смысл такой: в таблице trademarks поле isJurholder принимает 1 или 0, в зависимости от этого данные должны объединяться с таблицей или jurlica или fizlica. Можно ли как-то упростить запрос? Каким-нибудь условным выражением, не знаю)

РЕШЕНИЕ ВНИЗУ
Последний раз редактировалось java73 30.07.2015 19:47:49, всего редактировалось 2 раз(а).
java73
постоялец
 
Сообщения: 257
Зарегистрирован: 21.11.2013 09:08:10

Re: Помогите упростить SQL запрос (выборка из таблиц с услов

Сообщение Vadim » 21.07.2015 16:14:17

java73
У MSSQL и Firebird есть специальная функция IIF(), которая при выполнении условия возвращает одно значение, а при невыполнении - другое:
Код: Выделить всё
SELECT t.ID as tmID,
IIF(t.IsJurholder=TRUE, j.Shortname, CONCAT(f.Familia,' ',LEFT(f.Name,1),'.',LEFT(f.Otchestvo,1),'.') AS shortname
FROM trademarks t, jurlica j, fizlica f
WHERE t.ID IN (1,2,3,4)

Что получится - проверяйте сами. ;-)
Лично я бы воспользовался подзапросами.
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Помогите упростить SQL запрос (выборка из таблиц с услов

Сообщение java73 » 21.07.2015 16:24:21

Сделал такой:
Код: Выделить всё
USE investpatents;
SELECT trademarks.ID as tmID, IsJurholder, HolderID, Number,
jurlica.Shortname as JurName, fizlica.Familia as FizName
FROM trademarks
LEFT JOIN jurlica ON (IsJurholder=1 AND HolderID=jurlica.ID)
LEFT JOIN fizlica ON (IsJurholder=0 AND HolderID=fizlica.ID)
WHERE trademarks.ID IN (1,2,3,4,5);

но теперь два разных поля для разных таблиц. Попробую IIF сейчас, спасибо.

Добавлено спустя 39 минут 8 секунд:
Re: Помогите упростить SQL запрос (выборка из таблиц с условием)
Такой запрос перебирает все значения из таблиц fizlica и jurlicа, и соответственно дублирует много раз все значения из trademarks


Vadim писал(а): Vadim » 21.07.2015 16:14:17

java73
У MSSQL и Firebird есть специальная функция IIF(), которая при выполнении условия возвращает одно значение, а при невыполнении - другое:
КОД: ВЫДЕЛИТЬ ВСЁ
SELECT t.ID as tmID,
IIF(t.IsJurholder=TRUE, j.Shortname, CONCAT(f.Familia,' ',LEFT(f.Name,1),'.',LEFT(f.Otchestvo,1),'.') AS shortname
FROM trademarks t, jurlica j, fizlica f
WHERE t.ID IN (1,2,3,4)

Что получится - проверяйте сами.
Лично я бы воспользовался подзапросами.


Добавлено спустя 10 минут 51 секунду:
Re: Помогите упростить SQL запрос (выборка из таблиц с условием)
Вот так сработало:
Код: Выделить всё
USE investpatents;
SELECT DISTINCT t.ID AS tmID, t.HolderID AS th,
CASE t.IsJurholder
WHEN 1 THEN (SELECT Shortname FROM jurlica WHERE ID=th)
WHEN 0 THEN (SELECT Familia FROM fizlica WHERE ID=th) END AS Shortname
FROM trademarks t, jurlica j, fizlica f
WHERE t.ID IN (1,2,3,4,5);


Добавлено спустя 1 час 2 минуты 48 секунд:
Re: Помогите упростить SQL запрос (выборка из таблиц с условием)
В общем, не смотря на то, что с вашей помощью получилось два работающих SQL запроса, компоненты ZeosDB - ZQuery не хотят понимать их синтаксис.
Сделал в базе MySQL хранимаю процедуру с последним вариантом запроса, где ввел параметр Str (он подставляется в последнюю строку как раз, где IN (....).
Хранимая процедура почему-то возвращает только одну строку (((((((((((((((((((

не подскажете как быть?

Добавлено спустя 33 минуты 35 секунд:
Re: Помогите упростить SQL запрос (выборка из таблиц с условием)
Заработало все в лазарусе.
В свойстве SQL нужно прямо указывать базу данных перед таблицей:
Код: Выделить всё
       DM1.TMSelected.SQL.Add('SELECT DISTINCT trademarks.Number, CASE trademarks.IsJurholder');
       DM1.TMSelected.SQL.Add('WHEN 1 THEN (SELECT Shortname FROM investpatents.jurlica WHERE ID=HolderID)');
       DM1.TMSelected.SQL.Add('WHEN 0 THEN (SELECT CONCAT(Familia,'' '',LEFT(Name,1),''.'',LEFT(Otchestvo,1),''.'') FROM investpatents.fizlica WHERE ID=HolderID)');
       DM1.TMSelected.SQL.Add('END AS Shortname FROM investpatents.trademarks, investpatents.jurlica, investpatents.fizlica');
       DM1.TMSelected.SQL.Add('WHERE trademarks.ID IN ('+ID+')');
       DM1.TMSelected.Open;
java73
постоялец
 
Сообщения: 257
Зарегистрирован: 21.11.2013 09:08:10

Re: [НОВЫЙ ВОПРОС] Помогите упростить SQL запрос

Сообщение java73 » 30.07.2015 19:51:47

Друзья )))))))
вот текущий текст запроса:
Код: Выделить всё
SELECT DISTINCT trademarks.Number, IsJurholder, HolderID, trademarks.Address as PostAddress, Term,
CASE trademarks.IsJurholder
WHEN 1 THEN (SELECT Shortname FROM investpatents.jurlica WHERE ID=HolderID)
WHEN 0 THEN (SELECT CONCAT(Familia,' ',LEFT(Name,1),'.',LEFT(Otchestvo,1),'.')
FROM investpatents.fizlica WHERE ID=HolderID) END AS Shortname,
CASE trademarks.IsJurholder
WHEN 1 THEN (SELECT OGRN FROM investpatents.jurlica WHERE ID=HolderID)
WHEN 0 THEN (SELECT ' ') END AS HolderOGRN,
CASE trademarks.IsJurholder
WHEN 1 THEN (SELECT INN FROM investpatents.jurlica WHERE ID=HolderID)
WHEN 0 THEN (SELECT ' ') END AS HolderINN,
CASE trademarks.IsJurholder
WHEN 1 THEN (SELECT KPP FROM investpatents.jurlica WHERE ID=HolderID)
WHEN 0 THEN (SELECT ' ') END AS HolderKPP,
CASE trademarks.IsJurholder
WHEN 1 THEN (SELECT Address FROM investpatents.jurlica WHERE ID=HolderID)
WHEN 0 THEN (SELECT Address FROM investpatents.fizlica WHERE ID=HolderID)
END AS HolderAddress,
CASE trademarks.IsJurholder
WHEN 1 THEN (SELECT CONCAT(Familia,' ',LEFT(Name,1),'.',LEFT(Otchestvo,1),'.')
FROM investpatents.fizlica, investpatents.jurlica
WHERE fizlica.ID=jurlica.RukID AND jurlica.ID=HolderID)
WHEN 0 THEN (SELECT ' ') END AS RukFIO
FROM investpatents.trademarks, investpatents.jurlica, investpatents.fizlica
WHERE trademarks.ID IN (:IDlist);


В принципе он работает и очень быстро. Но я повёрнут на красоте, поэтому интересно, имеется ли возможность упростить его?
Как вы видете много полей из набора таблиц выбирается в зависимости от true или false значения одного поля: либо поля берутся из одной таблицы, либо из другой (или остаются пустыми).
Можно ли как убрать повторяющийся оператор CASE и сделать условный выбор нескольких полей из табли за один присест?

Пользуясь случаем, хотел бы поблагодарить еще раз всех, кто мне помогал с SQL здесь. Сидение на форуме заставляло мысли шевелиться, и в большинстве случаев решение находилось путем указания вами правильного направления для раздумий)
java73
постоялец
 
Сообщения: 257
Зарегистрирован: 21.11.2013 09:08:10


Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

Рейтинг@Mail.ru