for flooders
:: Главная :: Решения :: Статьи :: Сайт М. Дроздова :: Файловый архив :: Книга по VFP 9 :: Русский Help Online :: OFF-LINE Форум
   Лисоводы   всех   стран,  объединяйтесь !!!  

Список Форумов  :: Игры Разума
  

Решите задачку запросом
bcook
Автор

Сообщений: 160
Дата: 17.09.15 22:59:48
Здравствуйте!
Вот след. задачка.

Имеется некая таблица, вот ее структура:
поле id_k - идентификатор некой корзины для фруктов
поле id_fruit - идентификатор некоего фрукта, который лежит в соответствующей корзине.
Таблица заполнена сл. образом
id_k id_fruit
1 100
1 110
1 120

2 110
2 200

3 110
3 200
3 100

Задача. Возможно ли одним запросом выбрать
в каких корзинах вместе лежат фрукты с id_fruit 100 и 110

З.Ы. В качестве результата ожидаются id_k = 1 и 3
Ratings: 0 negative/0 positive

Re: Решите задачку запросом
pasha_usue

Сообщений: 3229
Откуда: Е-бург
Дата: 18.09.15 06:53:57
На этих исходных данных, возможно. Если на других данных есть дублирующиеся кортежи, их надо выкинуть подзапросом.
tcSearchFor = "100, 110"  
  lnSearchCount = GETWORDCOUNT(tcSearchFor, ",")  
    
  CREATE CURSOR CurFruits (Id_K I, Id_Fruit I)  
  INSERT INTO CurFruits (Id_K, Id_Fruit) VALUES (1, 100)  
  INSERT INTO CurFruits (Id_K, Id_Fruit) VALUES (1, 110)  
  INSERT INTO CurFruits (Id_K, Id_Fruit) VALUES (1, 120)  
    
  INSERT INTO CurFruits (Id_K, Id_Fruit) VALUES (2, 110)  
  INSERT INTO CurFruits (Id_K, Id_Fruit) VALUES (2, 200)  
    
  INSERT INTO CurFruits (Id_K, Id_Fruit) VALUES (3, 110)  
  INSERT INTO CurFruits (Id_K, Id_Fruit) VALUES (3, 200)  
  INSERT INTO CurFruits (Id_K, Id_Fruit) VALUES (3, 100)  
    
 *-* (IGEL) 1. Необходимо избавиться от дублирующихся кортежей. В постановке задачи их не встретилось,  
 *-* (IGEL) но дублирующиеся кортежи будут мешать следующему запросу.  
  SELECT DISTINCT * FROM CurFruits INTO CURSOR CurFruitsDist NOFILTER READWRITE  
    
 *-* (IGEL) 2. Фильтруем нужные фрукты и смотрим, чтобы в корзине было ровно столько фруктов, сколько в исходном условии  
  SELECT ;  
  	CL.Id_K ;  
  	FROM CurFruitsDist CL ;  
  	WHERE INLIST(CL.Id_Fruit, &tcSearchFor) ;  
  	GROUP BY CL.Id_K ;  
  	HAVING COUNT(Id_Fruit) = lnSearchCount ;  
  	INTO CURSOR CurResult NOFILTER READWRITE

PS. Сейчас в тему придет Игорь и скажет, что INLIST не оптимизируется по индексу. И надо использовать SQL-ный IN (...)



Исправлено: pasha_usue, 18.09.15 06:58
Ratings: 0 negative/0 positive

Re: Решите задачку запросом
Igor Korolyov

Сообщений: 32966
Дата: 18.09.15 13:59:42
pasha_usue
На этих исходных данных, возможно. Если на других данных есть дублирующиеся кортежи, их надо выкинуть подзапросом.
Необязательно подзапросом. Вполне сгодится в твоём варианте заменить having на
COUNT(DISTINCT Id_Fruit) = m.lnSearchCount
Конечно же в собственно "условии" в любом случае нельзя допускать дублей
pasha_usue
скажет, что INLIST не оптимизируется по индексу. И надо использовать SQL-ный IN (...)
INLIST вполне себе оптимизируется индексом. Но в целом работает чуть по другому нежели IN (изменение в 9-ке было сделано). И как раз если индекса нет (т.е. само условие не оптимизируемо), то мануал советует использовать IN - он чуть эффективнее работает если "список проверки" упорядочить, поставив в начало самые часто встречающиеся элементы.


------------------
WBR, Igor
Ratings: 0 negative/0 positive

Re: Решите задачку запросом
pasha_usue

Сообщений: 3229
Откуда: Е-бург
Дата: 21.09.15 07:07:55
Вот, о чем я и говорил. Пришел Игорь и все поправил (;Ж
Ratings: 0 negative/0 positive



Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 8 (Гостей: 8)

16.09.2019 05:01:19 exec: 0.11
Mem: 1.177 Mb

© 2000-2019 Fox Club 
Яндекс.Метрика