Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > SQL, базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.09.2009, 07:32   #1
ГиТ
 
Регистрация: 03.09.2009
Сообщений: 5
По умолчанию Помогите, кому не жалко, составить запрос

Доброго времени суток, уважаемые.
В SQL-конструкциях достаточно неопытен и вот возникла необходимость произвести определенную выборку для одного из скриптов. Можно, конечно же реализовать и программно, но, что-то мне подсказывает, что вместо нагромождений циклов и условий, можно обойтись правильным запросом, что существенно повысило бы скорость скрипта, а как этот самый запрос сделать - не знаю, в силу недостатка знаний в данной области.
Итак, вопрос.
Существует две таблицы, условно - Tab1 и Tab2.
Пусть ключом таблицы Tab1 является поле id_t1, таблицы Tab2 - соответсвенно, id_t2. Таблицы связаны между собой следующим образом: поле id_t1 таблицы Tab2 связано с ключом первой таблицы (т.е. туда вносим значения ключа). Кроме того, в таблице Tab2 имеется поле check, принимающее значение типа INT. Допустим, что существует некая переменная I типа INT с заданным значением.
Так вот, как выбрать из Tab1 все значения id_t1, не внесенные в id_t1 таблицы Tab2 в связке с тем же значением поля check, что и I. Т.е., если текущее значение id_t1 и появляется в таблице Tab2, то значение check != I.

ОНадеюсь, удалось более или менее понятнообъяснить. Заранее спасибо всем, кто откликнется.
С уважением.
[ подпись ]
ГиТ вне форума Ответить с цитированием
Старый 03.09.2009, 09:19   #2
SuperVisor
Павел Сергеевич
Форумчанин
 
Регистрация: 05.11.2006
Сообщений: 665
По умолчанию

Напиши для начала, просто это SQL или его спецификация? И чуть подробнее про базу..
Поля
Tab1: id;
Tab2: id, t1_id, check;
Также имеется некое значение I типа int...

Если не принимать во внимание этого некого I, то мы получим нечто вроде:
Код:
select Tab1.*
from Tab1
where not Tab.id in (select Tab2.t1_id from Tab2)
Познавая других, мы познаем себя.
С'est la vie...
SuperVisor вне форума Ответить с цитированием
Старый 03.09.2009, 09:20   #3
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

в какой среде (и через какое соединение) собираетесь свой запрос выполнять?

сам запрос очень простой (например так):
Код:
SELECT * FROM TAB1 
  where id_t1 not in 
    (select id_t1 from TAB2 where check <> I)
(вместо I нужно подставить конкретное значение, или использовать параметер запроса (синтаксис зависит от СУБД)

ДОБАВЛЕНО
SuperVisor - Вы опередили меня на целую минуту!

Последний раз редактировалось Serge_Bliznykov; 03.09.2009 в 09:22.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 03.09.2009, 09:45   #4
ГиТ
 
Регистрация: 03.09.2009
Сообщений: 5
По умолчанию

Уважаемые SuperVisor и Serge_Bliznykov, огромное Вам спасибо. Благодаря этому простому запросу с Вашей помощью скрипт просто полетел.

ЗЫ. Пишу на php.
ЗЗЫ. Уважаемый SuperVisor, объясните, если не тяжело, неучу, что такое спецификация SQL? В тривиальной связке Apache+MySQL+PHP что используется?
[ подпись ]
ГиТ вне форума Ответить с цитированием
Старый 03.09.2009, 09:50   #5
SuperVisor
Павел Сергеевич
Форумчанин
 
Регистрация: 05.11.2006
Сообщений: 665
Лампочка

Цитата:
Сообщение от ГиТ Посмотреть сообщение
ЗЗЫ. Уважаемый SuperVisor, объясните, если не тяжело, неучу, что такое спецификация SQL? В тривиальной связке Apache+MySQL+PHP что используется?
Ну, вы используете Apache+MySQL+PHP, а я - MSSQL-Transact SQL-Delphi.
Дак вот вы используете MySQL, а я - Transact-SQL. По сути это все один и тот же старый добрый SQL, но у каждого есть свои специфические возможности + разное именование функций/процедур. Поэтому сразу и уточнил. =)

Цитата:
SuperVisor - Вы опередили меня на целую минуту!
Я не специально )))))))
Познавая других, мы познаем себя.
С'est la vie...
SuperVisor вне форума Ответить с цитированием
Старый 03.09.2009, 12:50   #6
soleil@mmc
SQL-коддинг
Участник клуба
 
Регистрация: 16.01.2009
Сообщений: 1,192
По умолчанию

придется испортить всю малину
раз 10 пеерчитал условие задачи
Цитата:
Так вот, как выбрать из Tab1 все значения id_t1, не внесенные в id_t1 таблицы Tab2 в связке с тем же значением поля check, что и I. Т.е., если текущее значение id_t1 и появляется в таблице Tab2, то значение check != I.
этот запрос не катит
Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
Код:
SELECT * FROM TAB1 
  where id_t1 not in 
    (select id_t1 from TAB2 where check <> I)
объясняю наглядно на тестовых данных (по умолчанию подставим в кач-ве значения параметра число 500)
тестовый набор №1 (вариант запроса Serge_Bliznykov)
Код:
with
  tab1 as
  (select 1 id_t1 from dual union all
   select 2 from dual union all
   select 3 from dual union all
   select 4 from dual union all
   select 5 from dual union all
   select 6 from dual union all
   select 7 from dual
  ),
  tab2 as
  (select 1 id_t2, 1 id_t1, 500 i_check from dual union all
   select 2, 1, 200 from dual union all
   --select 3, 2, 500 from dual union all
   select 4, 2, 100 from dual union all
   select 5, 3, 500 from dual union all
   select 6, 3, 300 from dual union all
   select 7, 4, 500 from dual union all
   select 8, 4, 400 from dual union all
   select 9, 5, 500 from dual union all
   select 10, 5, 500 from dual union all
   select 11, 7, 300 from dual
  )
  
select id_t1
from tab1
where id_t1 not in (select id_t1 from tab2 where i_check <> 500)
Результат:
  • id_t1
  • 5
  • 6
в данном случае потеряли значение id_t1 = 2
а 5ка там точно есть

тестовый набор №2 (мой вариант запроса)
Код:
with
  tab1 as
  (select 1 id_t1 from dual union all
   select 2 from dual union all
   select 3 from dual union all
   select 4 from dual union all
   select 5 from dual union all
   select 6 from dual union all
   select 7 from dual
  ),
  tab2 as
  (select 1 id_t2, 1 id_t1, 500 i_check from dual union all
   select 2, 1, 200 from dual union all
   --select 3, 2, 500 from dual union all
   select 4, 2, 100 from dual union all
   select 5, 3, 500 from dual union all
   select 6, 3, 300 from dual union all
   select 7, 4, 500 from dual union all
   select 8, 4, 400 from dual union all
   select 9, 5, 500 from dual union all
   select 10, 5, 500 from dual union all
   select 11, 7, 300 from dual
  )
  
select id_t1
from tab1
where id_t1 not in (select id_t1 from tab2 where i_check = 500)
Результат:
  • id_t1
  • 2
  • 6
  • 7
soleil@mmc вне форума Ответить с цитированием
Старый 03.09.2009, 13:31   #7
SuperVisor
Павел Сергеевич
Форумчанин
 
Регистрация: 05.11.2006
Сообщений: 665
По умолчанию

Откровенно говоря, я тоже очень много раз перечитывал задачу.. И вообще не понял, при чем тут некая переменная I ) =)
Но автор статьи доволен... Будут проблемы - обратится еще раз )
Познавая других, мы познаем себя.
С'est la vie...
SuperVisor вне форума Ответить с цитированием
Старый 03.09.2009, 14:00   #8
soleil@mmc
SQL-коддинг
Участник клуба
 
Регистрация: 16.01.2009
Сообщений: 1,192
По умолчанию

проблемы с логическими ошибками очень трудно потом отлавливать

З.Ы.: эттаа... "се ля ви" у носителей языке пишется так "c'est la vie"
soleil@mmc вне форума Ответить с цитированием
Старый 04.09.2009, 13:25   #9
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
проблемы с логическими ошибками очень трудно потом отлавливать
точно так!


Цитата:
Сообщение от soleil@mmc
Код:
select id_t1
from tab1
where id_t1 not in (select id_t1 from tab2 where i_check = 500)
soleil@mmc, коллега, Вы абсолютно правы. именно так правильно.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 07.09.2009, 07:05   #10
ГиТ
 
Регистрация: 03.09.2009
Сообщений: 5
По умолчанию

Еще раз огромное спасибо всем, кто откликнулся и принял участие в оттачивании скрипта и поиску ошибок.
Логическую ошибку в первоначальном варианте скрипта я нашел сам и довольно скоро - все-таки, тестирование на практике располагает к отловле багов.
Первоначальное выражение было верным за исключением условия выборки значения с переменной I. Там действиетльно, необходимо ставить "=", а не "<>", иначе при получении данных они могут дублироваться либо теряться.
В любом случае, всем еще раз спасибо.
[ подпись ]
ГиТ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
помогите составить SQL запрос!!!! MAKSA БД в Delphi 12 07.08.2009 11:12
Помогите составить запрос или перепроектировать БД Neurotechnic БД в Delphi 1 27.07.2009 10:51
Кому не жалко для курсовой тестовой базы ruminaia Помощь студентам 2 27.05.2009 22:17
составить запрос к таблицам T1 и T2 MonteCarlos SQL, базы данных 13 03.02.2008 14:05