powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / Как решить задачу...
22 сообщений из 22, страница 1 из 1
Как решить задачу...
    #34560187
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть таблица "Товаров" (cod_item, name_item) и таблица "Сфер применения" (cod_app, name_app, prm_1, prm_2, ..., prm_N) этих товаров в соответствии с установленными критериями. Многие товары могут применятся в разных сферах, в зависимости от установленных критериев.
Как для выбранной группы товаров из таблицы "Товаров" (массив cod_item[]) сделать выборку строк из таблицы "Сфер применения" только общих для всех их сфер применения?
Какие будут предложения?
...
Рейтинг: 0 / 0
Как решить задачу...
    #34560277
AndrewNik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Для начала поменять структуру
...
Рейтинг: 0 / 0
Как решить задачу...
    #34560381
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AndrewNikДля начала поменять структуру
Если структуру базы данных, то она уже создана и ПО с ней работает. Не думаю, что это лучшее решение. А вот дописать окошко с DW, в котором можно будет увитеть то, что требуется, более реально. Пробовал создавать разные запросы и фильтры, но получается очень громоздко, а сомое главное - очень долго ждать результата в DW.

Или расшифруйте свое предложение.
...
Рейтинг: 0 / 0
Как решить задачу...
    #34560427
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AISЕсть таблица "Товаров" (cod_item, name_item) и таблица "Сфер применения" (cod_app, name_app, prm_1, prm_2, ..., prm_N) этих товаров в соответствии с установленными критериями. Многие товары могут применятся в разных сферах, в зависимости от установленных критериев.
Как для выбранной группы товаров из таблицы "Товаров" (массив cod_item[]) сделать выборку строк из таблицы "Сфер применения" только общих для всех их сфер применения?
Какие будут предложения?
Вы не знаете как написать запрос или как передать в него cod_item[] ?
Если первое, то Вам в другой форум .

Если второе, то надо в DWO, где будет запрос, объявить аргумент типа Number Array и потом передавать массив в dw.Retrieve(<сюда>).
В запросе же PowerBuilder разворачивает аргумент в список чисел, разделенных запятой.

Код: plaintext
1.
2.
SELECT
...
WHERE ... in (:an_idlist)


Код: plaintext
1.
2.
3.
4.
5.
6.
Dec{ 0 } ln_ids[]
ln_ids[] = { 1 ,  2 }
dw_1.Retrieve(ln_ids)
=>
SELECT
...
WHERE ... in ( 1 ,  2 )
но надо учитывать, что при пустом массиве будет следующая картина
Код: plaintext
1.
2.
3.
4.
5.
Dec{ 0 } ln_ids[]
dw_1.Retrieve(ln_ids)
=>
SELECT
...
WHERE ... in ()
поэтому вместо пустого массива нужно передавать массив с одним гарантированно несуществующим значением.
...
Рейтинг: 0 / 0
Как решить задачу...
    #34560660
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
SELECT
...
WHERE ... in (1, 2)


При таком запросе в DW будут все строки, т.е. как для 1-товара так и для 2-го. А надо только те что являються общими.
...
Рейтинг: 0 / 0
Как решить задачу...
    #34561315
PavelBuilder
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Согласен с AIS - надо менять структуру базы, а именно делать разрешение отношения через третью таблицу.
отношение "товар - сфера применения" - "многое ко многим", по классике создается третья таблица с множеством пар первичных ключей {(ID товара), (ID сферы применения)} простейшая реализация, удобные, быстрые запросы. По большому счету, сфера применения - классификатор, причём по хорошему иерархический и должен быть реализован в виде классфикатора (таблице с завязкой ключей самой на себя и желательно вспомогательную с плоским списком раскрытия иерархии, чтобы удобно было, но тут еще зависит от того какая база, у Оракла есть неплохие распишения pl sql на этот счёт ) Кроме того классификатор полезен не только для сфер применения, но и для других сущностей, которые так же можно хранить в той же таблице к примеру и обвязать все хранимками, что б совсем фантик был.
А попытка сделать то, что вы хотите на клиенте - это желание "выкрутится" и создать еще один костыль в систему. Рано или поздно вы допишетесь до такого что тошнить станет вас самих, а последователи что придут, когда вы уволитесь, будут преваться и клеймить предыдущее поколение разработчиков. Имейте совесть - уважайте профессию, пишите как надо и не ленитесь. Потом самим же себя будет уважать за что.

Сорри если обидел, но зато честно написал.
...
Рейтинг: 0 / 0
Как решить задачу...
    #34561761
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavelBuilder...надо менять структуру базы, а именно делать разрешение отношения через третью таблицу.
отношение "товар - сфера применения" - "многое ко многим", по классике создается третья таблица с множеством пар первичных ключей {(ID товара), (ID сферы применения)} простейшая реализация, удобные, быстрые запросы...

Спасибо за замечание. Так оно и есть. В начале, в условии задачи была допушена опечатка:
вместо
таблица "Сфер применения" (cod_app, name_app, prm_1, prm_2, ..., prm_N)
надо читать
таблица "Сфер применения" (cod_app, cod_item, prm_1, prm_2, ..., prm_N)

Но от этого, на мой взгляд, легче не стало.
...
Рейтинг: 0 / 0
Как решить задачу...
    #34562572
Фотография ЗоринАндрей
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
как то так?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
select distinct cod_app 
from "Сфер применения" сп1
where сп1.cod_item in (:cod_item[])
	and not exists (
		select  1  from "Товаров" 
		where "Товаров".cod_item in (:cod_item[]) 
		and "Товаров".cod_item not in 
		( 	select cod_item from "Сфер применения" сп2
			where сп2.cod_item in (:cod_item[]) and сп1.cod_app = сп2.cod_app ))
...
Рейтинг: 0 / 0
Как решить задачу...
    #34563041
VBRP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
test_sphera (cod_app, cod_item)
test_tovar (cod_item, name_item)


select app_name, count(*) from test_sphera
where cod_item in (1,2)
group by app_name
having count(*) = (select count(*) from test_tovar where cod_item in (1,2))
...
Рейтинг: 0 / 0
Как решить задачу...
    #34566450
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VBRPtest_sphera (cod_app, cod_item)
test_tovar (cod_item, name_item)


select app_name, count(*) from test_sphera
where cod_item in (1,2)
group by app_name
having count(*) = (select count(*) from test_tovar where cod_item in (1,2))


Этот вариант не подходит, т.к. выводит строки, в которых товар (в частности) имеет только две сферы применения. А если, например, оба товара имеют общих 5 сфер применения, то результат будет нулевой, а должен вывести 5 строк.

Пример от "ЗоринАндрей" почему то не получилось воссоздать.

Пока работает и достаточно быстро следующий пример:
Использую DataWindow в стиле CrossTab с параметрами,
где a_cod_item[ ] - массив выбранных тораров
a_prm = UpperBound( a_cod_item[ ])

ROWS - cod_app, COLUMNS - cod_item, VALUES - count(cod_item for crosstab)

select cod_app, cod_item
from tab_app
where cod_item in :a_cod_item

далее применяю фильтр на столбец "grand_count_cod_item"(crosstabcount(1)):
grand_count_cod_item = :a_prm

В результате получаю массив сфер применения подходящий для всех выбранных товаров.

И все-таки хотелось бы решить задачу как то иначе, не пошагово...
...
Рейтинг: 0 / 0
Как решить задачу...
    #34566470
VBRP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хм, станно, в моем случае при наличии 5ти общих сфер результат - 5 строк...


может быть я не правильно поняла структуру ваших данных?



select * from test_sphera

APP_NAME; COD_ITEM
DACHA; 1
DACHA; 2
OTPUSK; 1
OTPUSK; 2
DOM; 1
DOM; 2
DOM; 3
DOM; 4
CAR; 1
CAR; 2
CAR; 5
CAR; 6
SAD; 1
SAD; 3
SAD; 2
SAD; 5

select * from test_tovar
COD_ITEM; NAME_ITEM
1; TOV1
2; TOV2
3; TOV3
4; TOV4
5; TOV5
6; TOV6
7; TOV7
8; TOV8
9; TOV9
10; TOV10

where cod_item in (1,2)
group by app_name
having count(*) = (select count(*) from test_tovar where cod_item in (1,2))

APP_NAME; COUNT(*)
CAR; 2
DACHA; 2
DOM; 2
OTPUSK; 2
SAD; 2
...
Рейтинг: 0 / 0
Как решить задачу...
    #34566471
VBRP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
3-й sql-select не весь скопировала
т.е. для товара с cod_item = 1 и 2

полyчаем 5 строк-сфер: CAR, DACHA, DOM,OTPUSK, SAD

select app_name, count(*) from test_sphera
where cod_item in (1,2)
group by app_name
having count(*) = (select count(*) from test_tovar where cod_item in (1,2))


APP_NAME;COUNT(*)
CAR; 2
DACHA; 2
DOM; 2
OTPUSK; 2
SAD; 2
...
Рейтинг: 0 / 0
Как решить задачу...
    #34567523
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VBRPХм, станно, в моем случае при наличии 5ти общих сфер результат - 5 строк...


может быть я не правильно поняла структуру ваших данных?


Структура в принципе такая же, но у меня при Ваших данных выводит

APP_NAME; COUNT(*)
DACHA; 2
OTPUSK; 2

На мой взгляд из-за условия:

having count(*) = (select count(*) from test_tovar where cod_item in (1,2))

которое для данного примера равносильно:

having count(*) = 2
...
Рейтинг: 0 / 0
Как решить задачу...
    #34570894
VBRP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хм, какая у вас База Данных?

Все правильно, count(*) должно быть два. Этот каунт считает сколько раз КАЖДАЯ сфера встречается в запросе, а не СКОЛьКО всего РАЗНЫХ сфер в запросе.

В данном запросе у нас два товара, значит нас интересуют только те сферы, которые встречаются в запросе два раза. И не интересуют сферы, встречаюсчиеся 1 раз.

Если товаров будет 7, то нас будут интересоват' только те сферы, которые встречаются семь раз в запросе, по одной на каждый товар. И не интересуют те, которые стречаются 1-6 раза. Больше семи их не должно быть логически. Иначе это будет означать, что у вас для какого-то товара одна и та же сфера прилинкована более одного раза.

Пересмотрите внимательно весь запрос и сопоставьте с вашим. Очень трудно через транслит прописные истины об"яснять. Если у вас опять не получится, советую записаться на курсы по SQL.
...
Рейтинг: 0 / 0
Как решить задачу...
    #34572664
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VBRPХм, какая у вас База Данных?

Все правильно, count(*) должно быть два. Этот каунт считает сколько раз КАЖДАЯ сфера встречается в запросе, а не СКОЛьКО всего РАЗНЫХ сфер в запросе.

В данном запросе у нас два товара, значит нас интересуют только те сферы, которые встречаются в запросе два раза. И не интересуют сферы, встречаюсчиеся 1 раз.

База - Sybase SQL Anywhere.

Более точно задача звучит так:
У нас два товара и значит нас интересуют только те сферы, которые относятся как к 1-му так и ко 2-му товару. И не интересуют сферы, которые относятся только к 1-му из двух товаров.

Ваш запрос мне вывел строки, в которых просто у каждого Товара было две сферы применения, а меня интересует "совпадение".

Примечание: к чему вставлять (select count(*) from test_tovar where cod_item in (1,2)) если результат и так известен - это 2. Здесь больших знаний SQL по-моему не надо:)
VBRP
Если товаров будет 7, то нас будут интересоват' только те сферы, которые встречаются семь раз в запросе, по одной на каждый товар. И не интересуют те, которые стречаются 1-6 раза. Больше семи их не должно быть логически. Иначе это будет означать, что у вас для какого-то товара одна и та же сфера прилинкована более одного раза.

НЕ те, которые просто ВСТРЕЧАЮТЬСЯ семь раз в запросе, а те и только те, которые совпадают для семи товаров. Если совпадений нет, т.е. ни одна сфера не применима одновременна для каждого товара, то и строк не должно быть.
...
Рейтинг: 0 / 0
Как решить задачу...
    #34572952
Фотография Dmitry.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в соответствии с поставленной задачей VBRP предложила правильный запрос.

и если-таки не получается то:
VBRP Пересмотрите внимательно весь запрос и сопоставьте с вашим. Очень трудно через транслит прописные истины об"яснять. Если у вас опять не получится, советую записаться на курсы по SQL.

ЗЫ:
cod_item in (1,2)

имеется ввиду что там может быть in (1,2,3,...)
чтобы из датавиндов вы могли подставить массив в этот in
...
Рейтинг: 0 / 0
Как решить задачу...
    #34573151
VBRP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо Дим.

AIS, я своя запрос под оракл писала. Может быть выложите свой sql сюда, ну в котором 2 строки.

У меня такое подозрение, что Вы к таблице товаров обращаетесь, а не к таблице сфер.
...
Рейтинг: 0 / 0
Как решить задачу...
    #34573695
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VBRPСпасибо Дим.

AIS, я своя запрос под оракл писала. Может быть выложите свой sql сюда, ну в котором 2 строки.

У меня такое подозрение, что Вы к таблице товаров обращаетесь, а не к таблице сфер.

Это из DataWindow:
SELECT "app"."cod_app", count(*)
FROM "app"
WHERE "app"."cod_item" in (1,2)
GROUP BY "app"."cod_prep"
HAVING ( count(*) in (SELECT count(*) FROM "tovar" WHERE "tovar""."cod_item" in (1,2) ) )

Что не так?
А выдает при Retrieve строки
cod_app, count(*)
8, 2
26, 2
38, 2
40, 2
47, 2
50, 2
51, 2
52, 2
и т.д.
где например, см. 1-ю строку (cod_app=8) - просто в таблице АРР имеется две строки в которых есть 8 для 1-го товара , но ни одной 8 для 2-го.
Почему две строки (8-1), потому что товар 1-й имеет сферу применения 8, но по двум нормативам (критерию применения).
Выдает внешне правильно, но по сути не те сферы применения. Т.к. cod_app=6 отсутствует, а на сомом деле 1-й товар имеет разрешение к применению в сфере 6 по 5 нормативам, а товар 2-й по 8 нормативам.

Как быть дальше?
...
Рейтинг: 0 / 0
Как решить задачу...
    #34573762
Фотография Dmitry.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
либо задачу ставили некорректно, либо ответы не читаете...
--
кто такой "app"."cod_prep"?
почему в селекте одно поле а группируете по другому?
--
короче вот примерно запрос:
Код: plaintext
1.
2.
3.
4.
SELECT cod_app, count(distinct cod_item)
FROM app
WHERE cod_item in ( 1 , 2 )
GROUP BY cod_app
HAVING count(distinct cod_item) = (SELECT count(*) FROM tovar WHERE cod_item in ( 1 , 2 ) )
при условии что поле cod_item уникально в таблице tovar.
--
PS:если не полениться и перед выполнением запроса подсчитать кол-во елементов в массиве (1,2)
то лучше подзапрос select count(*) ... заменить на параметр с количеством
...
Рейтинг: 0 / 0
Как решить задачу...
    #34573836
VBRP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Все понятно.

У Вас к товару одна и таже сфера может быть прилинкована не один раз.
это меняет дело (запрос).

Только вот не знаю, как в вашей БД оператор distinct работает. Если не получится, то могу еще один запрос предложить.)))) У меня в голове множество комбинаций, но я ораклист(ка).

и пожалуйста используйте в запросе одинаковое поле: или app.cod_prep или app.cod_app для чистоты эксперимента.


select app_name, count(distinct cod_item) from test_sphera
where cod_item in (1,2)
group by app_name
having count(distinct cod_item) = (select count(*) from test_tovar where cod_item in (1,2))
...
Рейтинг: 0 / 0
Как решить задачу...
    #34573842
VBRP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Oj, tol'ko chto zametila, chto Dmitrij uzhe predlozhil gotovyj variant.

Sorry
...
Рейтинг: 0 / 0
Как решить задачу...
    #34586989
AIS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всё получилось. Ошибку понял. Осознал. Исправлюсь :)
Огромное спасибо персонально Dmitry и VBRP
за совет и за настойчивость в оказании помощи.
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / PowerBuilder [игнор отключен] [закрыт для гостей] / Как решить задачу...
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]