Гость
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Запрос для выборки записей через форму при связи многие ко многим / 9 сообщений из 9, страница 1 из 1
23.09.2019, 21:51
    #39865917
bratint
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос для выборки записей через форму при связи многие ко многим
Никак не могу разобраться. Есть БД книг, в одной таблице записаны книги, во другой - рубрики (художественная, детская, научная и т.п.). Каждая книга может относиться к нескольким рубрикам.

Надо, чтобы на форму можно было вывести все книги, относящиеся к определённым рубрикам.

Как вывести все книги, принадлежащие к одной рубрике - это понятно:
Код: vbnet
1.
Me.RecordSource = "SELECT * FROM Книги INNER JOIN КнВид ON Книги.Кн_ключ=КнВид.Кн_ключ WHERE Вид_ключ = " & Me.Список2


Но каким должен быть запрос, чтобы вывести книги, принадлежащие одновременно к нескольким рубрикам? Например, детские и художественные ?

Вариант с Книги INNER JOIN КнВид здесь, по-видимому, уже не подойдёт, поскольку, если, например, "Книга 1" принадлежит сразу к 2 рубрикам, то он даст для неё 2 строки:
Название Вид_ключКнига11Книга12
Т.е. в этой таблице не существует кортежа, который имел бы 2 значения "Вид_ключ", поэтому мы не сможем найти его через какое-либо условие WHERE. Способов решить это с помощью GROUP BY мне не удалось найти.

Единственное, что я смог придумать - это использовать множество запросов, например,

Запрос 1 - выводит ключи художественных книг:
Код: plaintext
SELECT КнВид.Кн_ключ FROM КнВид WHERE КнВид.Вид_ключ=1
Запрос 2 - выводит ключи детских книг:
Код: plaintext
SELECT КнВид.Кн_ключ FROM КнВид WHERE КнВид.Вид_ключ=2
Запрос 3 - выводит ключи детских и художественных книг:
Код: plaintext
SELECT Запрос1.Кн_ключ FROM Запрос1 INNER JOIN Запрос2 ON Запрос1.Кн_ключ=Запрос2.Кн_ключ

Но! Чтобы по такому принципу определялся источник записей формы, надо или реализовать этот запрос через одну строку, или динамически формировать подзапросы во время работы формы.
Первый вариант, конечно же, исключается, поскольку он невероятно сложен (с учётом того, что число рубрик не ограничено).
Реализовать второй - более реально, для этого надо динамически создавать/изменять запросы базы данных, которые служат источниками данных формы.

Вопрос в том, существуют ли какие-то другие, более простые/правильные способы решения этой задачи?
...
Рейтинг: 0 / 0
23.09.2019, 22:58
    #39865963
alecko
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос для выборки записей через форму при связи многие ко многим
bratint,
создаете список кодов, которым удовлетворяет та или иная книга
Код: vbnet
1.
2.
3.
4.
Dim str as string
str="1,2" ' каким то образом
'  и затем используете оператор IN
Me.RecordSource = "SELECT Кн_ключ FROM КнВид WHERE (Вид_ключ in (" & str & "));"
...
Рейтинг: 0 / 0
23.09.2019, 23:03
    #39865964
Шаман
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос для выборки записей через форму при связи многие ко многим
bratint,
Какая версия Access? 2003 или старше? По картинке вроде на 2003 смахивает.
Дело в том, что в 2007 появилась фишка с добавлением в одно поле нескольких значений.
Подобная ситуация, с выводом нужных значений, решается на раз-два без каких либо заморочек.
На всякий случай прикрепляю пример в формате accdb
...
Рейтинг: 0 / 0
24.09.2019, 00:09
    #39865982
ИВП
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос для выборки записей через форму при связи многие ко многим
Шаман,

Не надо учить плохому
...
Рейтинг: 0 / 0
24.09.2019, 08:13
    #39866032
4d_monster
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос для выборки записей через форму при связи многие ко многим
ШаманДело в том, что в 2007 появилась фишка с добавлением в одно поле нескольких значений.
Даже микрософт призывает никогда ей не пользоваться.
...
Рейтинг: 0 / 0
24.09.2019, 09:09
    #39866057
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос для выборки записей через форму при связи многие ко многим
Общий подход:

Код: vbnet
1.
2.
3.
4.
5.
SELECT список полей
FROM таблица-источник
WHERE рубрика IN ('рубрика 1', 'рубрика 2', ...)
GROUP BY список полей
HAVING COUNT (рубрика) = {количество рубрик в условии отбора}
...
Рейтинг: 0 / 0
24.09.2019, 14:48
    #39866363
bratint
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос для выборки записей через форму при связи многие ко многим
alecko, так не получится - этот запрос выдаст художественные или детские , а надо получить художественные и детские !

Шаман, Access 2002. Формат accdb не поддерживается :-(

Akina, спасибо, работает!!!
...
Рейтинг: 0 / 0
24.09.2019, 15:42
    #39866433
alecko
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос для выборки записей через форму при связи многие ко многим
bratint, да, точно - условие "и" можно реализовать через Not IN и ставить все другие категории кроме детских и художественных.
...
Рейтинг: 0 / 0
24.09.2019, 17:24
    #39866519
bratint
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Запрос для выборки записей через форму при связи многие ко многим
alecko, но тогда не выведутся книги, которые кроме 1 и 2 рубрик относятся ещё к каким-нибудь, а они должны быть. Здесь код Акины - самое то.

Может кому пригодится код для формы:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Dim str_vid As String
    
Sub MyPoisk()
Dim VarItm As Variant
Dim WasFirstVal As Boolean
    WasFirstVal = False
    str_vid = ""
    For Each VarItm In Список2.ItemsSelected
        If WasFirstVal = True Then
            str_vid = str_vid & ", "
        End If
        str_vid = str_vid & Список2.ItemData(VarItm)
        WasFirstVal = True
    Next VarItm
End Sub

Private Sub Список2_AfterUpdate()
    If Список2.ItemsSelected.Count > 0 Then
        MyPoisk
        Me.RecordSource = "SELECT Кн_ключ, Название, Год FROM Каталог WHERE Вид_ключ IN (" & str_vid & ") GROUP BY Кн_ключ, Название, Год HAVING COUNT(Вид_ключ)=" & Список2.ItemsSelected.Count
    End If
End Sub

Каталог - это Книги inner join КнВид. Не забудьте также включить несвязное выделение в параметрах списка.
...
Рейтинг: 0 / 0
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / Запрос для выборки записей через форму при связи многие ко многим / 9 сообщений из 9, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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