|
Формирование запроса
|
|||
---|---|---|---|
#18+
Добрый день! Предположим есть некая таблица, id(уникальный записи) id1 (№ карточки) f1,f2 - поля карточки. id id1 f1 f2 1 1 А1 С1 2 1 А2 С1 3 2 В1 Р1 4 3 X1 Z1 5 3 X1 Z2 ... В таблице хранятся карточки, которые могут состоять из нескольких или одной записи (id1 - № карточки). ? как вытащить всю карточку, например по условию f1=А1, т.е. получить должен две записи id=1 и id=2. select * from t1 where id1 in (select distinct id1 from t1 where f1=А1) Такой запрос правильный, но для больших таблиц (>400000) и внутренней выборке (2000) выполняется медленно, что на ORACLE,MSSQl, про IB вообще молчу. Индексы все есть. Какие есть еще варианты выполнения такого запроса или другой организации БД? Вариант: select b.* from test a inner join test b on a.id1 = b.id1 where a.f1=A1 замечательный, но возвращает много дублей, с которыми надо бороться. Искренне признателен. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.01.2003, 17:08 |
|
Формирование запроса
|
|||
---|---|---|---|
#18+
Как писал Алексей Ковязин, не вникая в подробности заменяй IN на EXISTS. ... |
|||
:
Нравится:
Не нравится:
|
|||
14.01.2003, 19:39 |
|
Формирование запроса
|
|||
---|---|---|---|
#18+
Имхо, эти два запроса select * from t1 where id1 in (select distinct id1 from t1 where f1=А1) select b.* from t1 where exists (select id1 from t1 a where a.id1 = b.id1 and a.f1=A1) ничем не отличаются. Внутренний и внешний запросы, но как говорит (Попов на ibase.ru и мой собственный опыт), на Ib (у меня клоны 6.0, может на 6.5 и 7.0 иначе) подзапрос фактически выполняется для каждой записи внешнего запроса. По-этомв вариант: select b.* from test a inner join test b on a.id1 = b.id1 where a.f1=A1 мне нравится больше, но как убрать дубли? Добавление distinct ничего не дает, скорость падает стремительно. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2003, 03:29 |
|
Формирование запроса
|
|||
---|---|---|---|
#18+
Сделай хранимую процедуру. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2003, 10:59 |
|
Формирование запроса
|
|||
---|---|---|---|
#18+
Привет! Честно говоря, ломает разбираться в неформализованном описании твоей проблемы. На это же время нужно, причем непроизводительно затрачиваемое. Вот если бы COPY-PASTE структуры таблиц, текст проблемного запроса, его план, результаты - что получается, и что нужно получить, тогда бы можно подумать над советом. Ведь цель форума - обмен опытом и мнениями, а не бесплатное обучение. Есть тут изрядная разница. Прежде всего в том, чтобы человек через полгода набрал в поиске слова по проблеме, а ему выдало бы четкие письма с рекомендациями и ясно сформулированными советами. Пожалуйста, формулируйте вопросы абсолютно ясно и недвусмысленно, оформляйте их красиво... Тогда и ответы будут ясными и четкими. C уважением, Алексей. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2003, 11:53 |
|
Формирование запроса
|
|||
---|---|---|---|
#18+
>Имхо, эти два запроса >select * from t1 where id1 in (select distinct id1 from t1 where f1=А1) >select b.* from t1 where exists (select id1 from t1 a where a.id1 = b.id1 and >a.f1=A1) >ничем не отличаются. Безобразие! Не разводите смуту!!! Эти эапросы отличаются кардинальным образом - запрос с IN заменяется на кучу проверок OR, а т.к. IB выполняет проверку всех логических выражений, то логично предположить, что запрос IN будет сильно тормозить. Можно попробовать заменить на SOME/ANY - не помню, что эта двоица там делает. Где-то статья была по этому поводу, кажись на ibase.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2003, 11:58 |
|
Формирование запроса
|
|||
---|---|---|---|
#18+
>Алексей Ковязин. >Ведь цель форума - обмен опытом и мнениями, а не бесплатное обучение. >Есть тут изрядная разница. По правде говоря, я не думаю, что для меня здесь бесплатное обучение, несколько вариантов я сам привел. Просто, к слову. Попробую изложить. create table test(id integer, id_car integer, f_znak char(10), f2 char(10)) insert into test values (1, 1, 'A1', 'С1') insert into test values (2, 1, 'А2', 'С1') insert into test values (3, 2, 'В1', 'Р1') insert into test values (4, 3, 'X1', 'Z1') insert into test values (5, 3, 'X1', 'Z2') Например, мы имеем объект автомобиль - карточка. Он сегодня имеет один госномер, завтра другой, послезавтра транзит. Сохраним эту историю в приведенной выше таблице. id - это просто уникальный ключ, id_car-идентификатор машины, f_znak - рег.знак, f2- любые другие поля. Задаем условие поиска: f_znak like 'А1%'. Задача - получить не все записи, удовлетворяющие поставленным условиям, а полностью карточки. При таком условии я должен получить две записи: 1,1,A1,C1 2,1,A2,C1 а не только ту, у которой id=1. Эту задачу решает запрос: select * from test where id_car in (select id_car from test where f_znak like 'A1%') Но, как вы знаете, использование подзапросов в IB смерти подобно. По-этому я пытаюсь найти другой вариант SQL запроса, некоторого стандартного, пример я привел в других ответах. Использование tmp таблиц не очень разумно, выборки составляют до 10000 карточек, а хочется чтобы ответ был получен быстро. Буду благодарен, если кто-нибудь поделится мыслями. Индексы специально не создавал. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2003, 16:33 |
|
Формирование запроса
|
|||
---|---|---|---|
#18+
>GOLD Посмотрите план запроса select a.* from test a where exists (select id_car from test b where a.id_car = b.id_car and b.f_znak like 'A1%') PLAN (B NATURAL) PLAN (A NATURAL) (natural - понятно, нет индексов), но суть то все равно одна и та же - внутренний подзапрос и внешний. Кроме того, я проверял выполнение на других, подобных, реальных данных, с индексами, очень много записей - время выполнения IN и EXISTS одно и тоже. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.01.2003, 16:40 |
|
Формирование запроса
|
|||
---|---|---|---|
#18+
Привет! таблица Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24.
данные Код: plaintext 1. 2. 3. 4. 5.
запрос Код: plaintext 1. 2. 3.
План на yaffil 1.0 Код: plaintext 1. 2. 3. 4.
результаты Код: plaintext 1. 2.
И все же купи Грабера! Примечание - yaffil на like в подходящих случаях использует индекс. WBR, Alexey. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.01.2003, 12:55 |
|
Формирование запроса
|
|||
---|---|---|---|
#18+
Добрый день, Алексей. К сожалению,я забыл это повторить, Вы не обратили внимание на предыдущие письма, касательно дублей.. С Like 'A1%' у меня проблем не было. Проблемы с like 'X1%' select tc.id, tc.id_car, tc.f_znak, tc.f2 from testcard tc join testcard tc2 on (tc.id_car=tc2.id_car and tc2.f_znak like 'X1%') ID ID_CAR F_ZNAK F2 4 3 X1 Z1 4 3 X1 Z1 5 3 X1 Z2 5 3 X1 Z2 Вопрос, как убрать дубли. Грабер советует делать запрос ассиметричным, вводом дополнительного условия. Но пример, приведенный им не подходит, надо чтобы и с A1 работало и с X1. Тем более, что это только маленькая часть таблицы, в ней гораздо больше полей. Вопрос чисто теоретический, как сделать так, чтобы при f_znak like 'A1%' возвращалось ID ID_CAR F_ZNAK F2 1 1 A1 c1 2 1 A2 c1 а при f_znak like 'X1%' ID ID_CAR F_ZNAK F2 4 3 X1 Z1 5 3 X1 Z2 Приведенный мной ранее запрос с подзапросом решает эту пробему, но на IB, при больших данных это смерти подобно, он внутренний подзапрос делает по индексу, в внешний natural. Вот я и думаю, как решить эту проблему, вплоть до создания некой другой структуры хранения данных. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.01.2003, 05:37 |
|
Формирование запроса
|
|||
---|---|---|---|
#18+
Код: plaintext 1. 2. 3.
Код: plaintext 1. 2. 3. 4.
Код: plaintext 1. 2.
К сожалению,я забыл это повторить, Вы не обратили внимание на предыдущие письма, касательно дублей.. С Like 'A1%' у меня проблем не было. Проблемы с like 'X1%' Так какого же хрена, прошу прощения, приводить в письме #7 в данной теме, после настойчивой просьбы подробно и однозначно изложить проблему методом COPY-PASTE, появляется группа примеров с перемешанными русско-английскими буквами (ведь их исправлять пришлось для внесения в базу), да еще и с тестовым примером, скрывающим какую либо проблему? Имхо, СРОЧНО нужно прочитать ВОТ ЭТУ СТАТЬЮ . WBR, Alexey ... |
|||
:
Нравится:
Не нравится:
|
|||
17.01.2003, 11:37 |
|
Формирование запроса
|
|||
---|---|---|---|
#18+
Алексей, прошу прощения за COPY-PASTE ошибку, недоглядел. В письме №1 было все правильно.Обещаю, больше такое не повторится, буду точен и лаконичен, как спартанец. Теперь по существу. Вариант с distinct я знаю. Он включает в себя сортировку. Я запускал подобный запрос на 300000 записей, вытащить надо было 3000 карточек. Запрос выполнялся очень долго, план запроса, тот же, что Вы и указали. Я вот думаю, есть ли какой-нибудь вариант с UNION, вначале добавить условие a.id!=b.id, это по идее должно сделать все правильно для X1, но для A1 вытащит только одну, или наоборот. И добавить Union недостающите, но как? Ну не дает мне покоя мысль, точно ли надо делать сортировку или промежуточную выборку для получения нужных мне данных. Нет ли другого варианта. В любом случае, обещаю, если найду - опубликую. ... |
|||
:
Нравится:
Не нравится:
|
|||
17.01.2003, 13:11 |
|
|
start [/forum/topic.php?fid=40&fpage=529&tid=1580942]: |
0ms |
get settings: |
8ms |
get forum list: |
11ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
28ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
41ms |
get tp. blocked users: |
1ms |
others: | 309ms |
total: | 417ms |
0 / 0 |