Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft Access Новый топик    Ответить
 Как реализовать правильную выборку в Access  [new]
Siompc
Member

Откуда:
Сообщений: 203
Здравствуйте. Подскажите как лучше и с меньшим временем сделать запрос на выборку таблицы "Запросы".

Структура такая:
Код - ключевое поле, счетчик
От - числовое (код пользователя, который пишет запрос)
Кому - числовое (код пользователя, кому пишем)
Запрос - текст запроса
Дата - соответственно дата этого запроса

Нужно сделать такой запрос, который будет возвращать последние запросы пользователя.
Например:
Есть пользователи 1,2,3,4. Они друг другу могут отправлять запросы. Например 1 отправил 2, 3 и 4. В ответ на это 3 и 2 отправил встречный запрос. После этого 1 шлет дополнительно 2-му. Получилось в таблице так:

[ОТ] [КОМУ] [ДАТА]
1 2 11:10
1 3 11:15
1 4 11:20
2 1 11:25
3 1 11:30
1 2 12:00

Теперь надо как-то сделать так, что бы 1 пользователь получил все свои и чужие последние запросы. Я так понял нужно делать выборку по коду пользователя. Но он в двух столбцах сразу.... результат должен быть таким:

[ОТ] [КОМУ] [ДАТА]
1 4 11:20
3 1 11:30
1 2 12:00

Как это сделать? =)

Модератор: Тема перенесена из форума "MySQL".
25 мар 19, 00:29    [21842310]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
vmag
Member

Откуда: MP
Сообщений: 3205
Siompc
Теперь надо как-то сделать так, что бы 1 пользователь получил все свои и чужие последние запросы.


не понятно... последние это сколько 5 ? 10 ? 100 ? за период ?

Siompc
результат должен быть таким:


типа от балды ?
Попробуй объяснить почему есть в результате строки

Siompc
1 4 11:20
3 1 11:30
1 2 12:00


и почему нет остальных, если в них 1 есть либо слева, либо справа ?
А так-то можно два запроса вставить в UNION ALL, в одном (одно и то же) условие на первый столбец, в другом на второй...
25 мар 19, 01:48    [21842331]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
Siompc
Member

Откуда:
Сообщений: 203
Обьясняю. Получить надо все. Подставить потом TOP N не трудно.

Результат же не от балды.
Если запрос идет от 1 пользователя к 2 или наоборот это считается одна ветка запросов. Между этими пользователями. Следовательно если пользователь с ИД 1 получает список запросов, то нужно отсеять последние по времени и те, которые назначались ему, либо он отправлял.
Он отправил 3 пользователю, пользователь отправил встречное. Следовательно выборка должна отобрать только последний запрос

3 1 11:30

Пользователь с ИД 4 не отправлял запрос встречный. Следовательно он один у этих пользователей. Выводится как есть.

1 4 11:20
25 мар 19, 02:05    [21842335]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
vmag
Member

Откуда: MP
Сообщений: 3205
Siompc,

спасибо за разъяснение, теперь понятно - нужно выводить один, последний по времени в каждой паре, независимо от положения сторон диалога...
union наверно не покатит... а юзеров сколько теоретически ?
25 мар 19, 02:19    [21842339]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
vmag
Member

Откуда: MP
Сообщений: 3205
Siompc,

Собственно, если юзеру важно только последнее, то таблицу
1 2 11:10
1 3 11:15
1 4 11:20
2 1 11:25
3 1 11:30
1 2 12:00
в запросе можно получить так (отсортировав юзеров в строке)
1 2 11:10
1 3 11:15
1 4 11:20
1 2 11:25
1 3 11:30
1 2 12:00
и тогда после группировки можно выцепить максимальное время:
1 4 11:20
1 3 11:30
1 2 12:00
ну типа первому будет понятно в последний раз с кем он когда...
25 мар 19, 02:40    [21842340]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 19142
Для выделения диалогов в запросе вычислите выражения Min([ОТ], [КОМУ]) AS MinID и Max([ОТ], [КОМУ]) AS MaxID. Группировка по этим полям даст диалог, а соответственно MAX([ДАТА]) AS Max_Data - это время последнего сообщения в диалоге. По полученным трём значениям получаете сами сообщения.
25 мар 19, 07:46    [21842393]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
court
Member

Откуда:
Сообщений: 1775
Siompc,

так можно, но запрос не "лёгкий" будет ... индекс на [ДАТА] рекомендую
select
	*
from Tab t1	 
where (select count(*) from Tab t2 where t2.[ОТ] in (t1.[ОТ],t1.[КОМУ]) and t2.[КОМУ] in (t1.[ОТ],t1.[КОМУ]) and t2.[ДАТА]>=t1.[ДАТА]) = 1
25 мар 19, 10:52    [21842497]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
Озверин
Member

Откуда: Ростов-на-Дону
Сообщений: 5183
Siompc, по аналогии с цепочками сообщений в почтовом ящике(gmail, например)?
25 мар 19, 10:59    [21842506]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
Siompc
Member

Откуда:
Сообщений: 203
vmag,
Юзеров будет много )) В теории их не ограничено.

Озверин,
Да, можно сказать и так ) По типу цепочки диалогов.

Не ожидал столько ответов ) Спасибо вам.
Может для ускорения запроса и облегчения работы с ним еще одну таблицу сделать? Если это упростит решение? Или например добавить колонку в этой таблице, в которой будет хранится строка "Меньший ИД пользователя & Больший ИД пользователя", и по ней потом делать выборку? Сильно это повлияет на производительность и размер?
25 мар 19, 15:54    [21842919]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
vmag
Member

Откуда: MP
Сообщений: 3205
Siompc
Может для ускорения запроса и облегчения работы с ним еще одну таблицу сделать? Если это упростит решение? Или например добавить колонку в этой таблице, в которой будет хранится строка "Меньший ИД пользователя & Больший ИД пользователя", и по ней потом делать выборку? Сильно это повлияет на производительность и размер?


В принципе вам ничто не мешает проверить всё на том что есть, Аkina фактически реализовал то, что я предложил в теории, теоретически дополнительная колонка меньший/больший ИД большого эффекта по времени скорее всего не даст ибо основное время съест и так и эдак группировка и вычисления, а вот увеличение физической памяти будет заметно (юзеров то много, а общений еще больше)...
25 мар 19, 20:11    [21843137]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
vmag
Member

Откуда: MP
Сообщений: 3205
Siompc,

Там еще с "Меньший ИД пользователя & Больший ИД пользователя" есть один нюанс нужно отбор юзера делать по обоим ИД, пример для юзера 2:
- исходная таблица
1 2 11:10
2 5 12:05
6 2 12:10
2 5 12:15
- после сортировки
1 2 11:10
2 5 12:05
2 6 12:10
2 5 12:15
- результат для юзера 2 (первую строку можно потерять при неверном условии отбора)
1 2 11:10
2 5 12:15
2 6 12:10
Ситуация когда юзер с меньшим ИД обратился к юзеру со старшим ИД, тот не ответил, а статистика нужна по юзеру со старшим ИД (больший ИД остается справа).
- Как вариант сразу отбирать записи в которых искомый юзер есть или слева или справа, формировать одно общее поле юзеров (писать слева искомого юзера+разделитель+справа второго юзера) ну и потом группировка и максимумы...
25 мар 19, 20:49    [21843178]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
Siompc
Member

Откуда:
Сообщений: 203
vmag,
Хм... Работать с таблицей будет программа, поэтому есть возможность при приходе запроса проверять ID пользователей. Например сделать таблицу так:

Диалог - строка 20 символов
От
Кому
Запрос
Дата

И далее программа будет при приходе заносить в поле "диалог" значение минимальный код пользователя и максимальный.
Попробую записать так:

14 1 4 "_" 11:20
14 4 1 "_" 11:25
12 2 1 "_" 12:55
13 1 3 "_" 13:23

Вот в таком случае можно ли сделать выборку таким образом?
SELECT
[вставить DISTINCT Диалог ???]
* FROM Запросы WHERE От=1 OR Кому=1 ORDER BY Дата DESC

Что бы отобрать все доступные, а потом исключить повторения по столбцу "Диалог"...
Или это я сильно простой жизни хочу? ))
25 мар 19, 22:03    [21843215]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
vmag
Member

Откуда: MP
Сообщений: 3205
Siompc,

В рамках условий первого поста:
PARAMETERS ИД Long;
SELECT IIf([От]=[ИД],[От] & "-" & [Кому],[Кому] & "-" & [От]) AS Диалог, Max(Запросы.Дата) AS [Max-Дата]
FROM Запросы
WHERE (((Запросы.От)=[ИД])) OR (((Запросы.Кому)=[ИД]))
GROUP BY IIf([От]=[ИД],[От] & "-" & [Кому],[Кому] & "-" & [От]);


-На вход запроса в качестве параметра подается ИД юзера, по которому нужна статистика
-На выходе последние Дата/Время от всех юзеров с кем общался испытуемый юзер
-Естественно диалект акцеса, проверял на обоих примерах, результаты верные
26 мар 19, 00:19    [21843287]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
Siompc
Member

Откуда:
Сообщений: 203
vmag,
Спасибо за помощь! )) Работает шикарно, правда не пойму как он делает группировку по условию...

SELECT Max(Запросы.Дата) as t1
FROM Запросы
WHERE (Запросы.От=1) OR (Запросы.Кому=1)
GROUP BY IIf([От]=1,[От] & "-" & [Кому],[Кому] & "-" & [От]);

Тут чуть-чуть не годится, потому что программе, которая это обрабатывает, нужно получить все данные таблицы этой. А не только дату.
Перечислять поля в select не годится... так как при изменении имени полей - придется переписывать код программы. Это проблематично. Поэтому надо вывести все столбцы с этим условием отборки. Если тут менять select * as T1, Max(Запросы.Дата) as t2
выдаст ошибку.
26 мар 19, 03:07    [21843324]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 19142
Siompc
не пойму как он делает группировку по условию
Чтобы понять - удали группировку, а выражение группировки помести в список вывода и отсортируй по нему.
26 мар 19, 07:34    [21843374]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
ПЕНСИОНЕРКА
Member

Откуда: Владимирская обл
Сообщений: 4568
Siompc,
добавила пару строк и комментарий
КодОТКОМУДАТА
11201.03.2019
21302.03.2019
31403.03.2019
42104.03.2019
53105.03.2019
61208.03.2019
72309.03.2019
83403.03.2019
94303.03.2019


SELECT w.ОТ, w.КОМУ, Max(w.ДАТА) AS [Max-ДАТА],
iif(sum(w.pol)=sum(w.otpr),"ответ получен",
iif(sum(w.pol)>sum(w.otpr),"письмо послано","жду письма"))
FROM (SELECT  [ОТ], [КОМУ], [ДАТА],1 as pol,0 as otpr  FROM tab
union all
SELECT   [КОМУ],[ОТ], [ДАТА],0,1 FROM tab)  AS w
GROUP BY w.ОТ, w.КОМУ;

ОТКОМУMax-ДАТАExpr1003
1208.03.2019письмо послано
1305.03.2019ответ получен
1403.03.2019письмо послано
2108.03.2019жду письма
2309.03.2019письмо послано
3105.03.2019ответ получен
3209.03.2019жду письма
3403.03.2019ответ получен
4103.03.2019жду письма
4303.03.2019ответ получен
26 мар 19, 08:56    [21843400]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
vmag
Member

Откуда: MP
Сообщений: 3205
Siompc
программе, которая это обрабатывает, нужно получить все данные таблицы этой. А не только дату.


Собственно если немного подумать, то при подходе выше (одно поле кто - кому с искомым в начале) :
- вместо Max(Запросы.Дата) можно ловить Max(Запросы.Код), должно быть быстрее и тоже самое ибо записи идут последовательно по возрастанию счетчика и дата/время.
- соответственно остальные поля из таблицы должы легко выдергиваться по Last
- ниже пример, в котором из таблицы берется например еще одно текстовое поле Сообщение
PARAMETERS ИД Long;
SELECT IIf([От]=[ИД],[От] & "-" & [Кому],[Кому] & "-" & [От]) AS Диалог, Max(Запросы.Дата) AS [Max-Дата], Last(Запросы.Сообщение) AS [Last-Сообщение]
FROM Запросы
WHERE (((Запросы.От)=[ИД])) OR (((Запросы.Кому)=[ИД]))
GROUP BY IIf([От]=[ИД],[От] & "-" & [Кому],[Кому] & "-" & [От]);
26 мар 19, 12:46    [21843635]     Ответить | Цитировать Сообщить модератору
 Re: Как реализовать правильную выборку в Access  [new]
Siompc
Member

Откуда:
Сообщений: 203
vmag,
Разобрался ))) Шикарно. Через пару дней попробую в программе - отпишусь!
СПАСИБО!
26 мар 19, 17:26    [21844079]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft Access Ответить