гороскоп на сегодня у скорпиона любовный гороскоп совместимости любовный гороскоп на 2017 рак девушка подробнее на этой странице нажмите чтобы увидеть больше ссылка на подробности любовный гороскоп гороскоп совместимости совместимость знаков в любви любовный гороскоп любовный гороскоп гороскоп совместимости парень козерог девушка весы гороскоп совместимость гороскоп на месяц любовный рак гороскоп на след неделю девы любовный гороскоп женщина рыба мужчина весы совместимость гороскоп совместимости он телец она овен совместимость любовный увидеть больше гороскоп дева любовный на сегодня и завтра гороскоп основываясь на этих данных на этой странице гороскоп на совместимость телец и рыбы рак гороскоп весы стрелец совместимость на 2017 год гороскоп ссылка сегодня гороскоп совместимость по гороскопу женщина телец мужчина рак совместимость гороскоп секс гороскоп совместимости читать больше гороскоп любовный на сегодня козерогу гороскоп любовный на завтра для стрельца гороскоп любовный на месяц рыбы женщина совместимость гороскопа лев и овен нажмите для продолжения любовный гороскоп двух львов гороскоп неделю гороскоп стрелец женщина и весы мужчина совместимость в браке гороскоп совместимости весы жен овен муж подробнее на этой странице сексуальный гороскоп близнецы женщин гороскоп совместимости она водолей он телец основываясь на этих данных совместимость по гороскопу близнецы скорпион гороскоп совместимости рак и козерог на 2017 гороскоп козы на 2017 любовный гороскоп на завтра лев любовный женщина одинокая перейти увидеть больше совместимость по гороскопу рыба и дева гороскоп женщины любовный гороскоп скорпиона на 2017 год мужчина гороскоп пифагора совместимости знаков зодиака привожу ссылку любовный гороскоп на рыб сегодня по ссылке гороскоп таблица совместимости по годам сексуальный гороскоп водолея и овна любовный гороскоп на месяц для овнов гороскоп совместимости рыбы женщина и рак мужчина совместимость нажмите чтобы увидеть больше гороскоп совместимости по луне и солнцу вот ссылка гороскоп на совместимость женщина телец любовный гороскоп на месяц весы 2017 гороскоп дева телец совместимость совместимость гороскопов лев скорпион посетить страницу гороскоп совместимости знаков зодиаков таблица фото гороскоп совместимости рыба тигр любовный гороскоп женщина козерог 2017 любовный гороскоп козерог на сегодня женщина любовный гороскоп для девы на сегодня и завтра гороскоп стрелец на завтра женщина любовный составить любовный любовный гороскоп водолей на 2017 гороскоп совместимости по знакам зодиака овен и водолей

Форумы HiProg.com - MS ACCESS, VBA, VB

 

Ответить на сообщение

Вернуться к теме

Вы отвечаете на сообщение:

ник: час
сдеся на сайте имеется статья
http://hiprog.com/index.php?option=com_content&task=view&id=334&Itemid=35
http://am.rusimport.ru/MsAccess/f2.aspx?id=18959


Слияние полей из разных строк запроса.      
Автор Юрий Шерман     
16.01.2002 г.  
Как соединить данные полей из разных строк запроса в одно поле? Вашему вниманию предлагается оптимальное решение. 
Автор: Юрий Шерман
http://www.tour-soft.com/ 

Слияние полей из разных строк запроса. Новая версия.
 
Для полей из разных строк запроса в SQL имеется целый ряд групповых функций: Sum, Min, Max и т.д. Однако если Вам надо объединить поля из разных строк, разделяя их, например, запятой, то такой групповой операции Вы не найдете. Придется писать собственное решение.

Постановка задачи.
Пусть у Вас имеется Tab1 (таблица или запрос) с полями: ID и Fam. 
ID - групповой номер, он может повторяться, но не пуст (для упрощения). 
Fam - поле с фамилией.

Требуется создать запрос TabUnion с двумя полями: 
- ID, значения которого взяты из Tab1, но не повторяются;
- FamUnion, которое состоит из списка фамилий через запятую. 
Список должен состоять из фамилий с одним ID.

Рассмотрим решение задачи от самого простого случая до самого общего. 

Случай 1. Имеются упрощающие предположения.
Предположение 1: Tab1 должна быть таблицей, отсортированной по ID.
Предположение 2: в Tab1 должно быть не менее двух различных значений ID.
Предположение 3: пустых фамилий нет.

Текст запроса TabUnion1:
Select ID, Last(UnionStr1(ID,Fam)) AS FamUnion FROM Tab1
GROUP BY ID;

Описание функции UnionStr1:

Public Function UnionStr1(ID, Fam)
Static IDOld, FamUnion
If IDOld <> ID Then
IDOld = ID
FamUnion = Null
End If

FamUnion = (FamUnion + ", ") & Fam
UnionStr1 = FamUnion
End Function 

Оценка скорости: время обработки пропорционально C*n, где C – константа, n – количество записей в Tab1. Очевидно, что оценку улучшить нельзя. То есть метод оптимален.

Случай 2. Отличается от случая 1 снятием предположения 2.
То есть, допускается случай, когда все записи Tab1 имеют один ID.
Тогда приходится заниматься установкой начального значения IDOld.

Текст запроса TabUnion2:
Select ID, Last(UnionStr2(ID,Fam)) AS FamUnion 
FROM Tab1
WHERE IsEmpty(UnionStr2())
GROUP BY ID;

Описание функции UnionStr2:

Public Function UnionStr2(Optional ID, Optional Fam)
Static IDOld, FamUnion
If IsMissing(ID) Then
IDOld = Empty
Exit Function
End If
If IDOld <> ID Then
IDOld = ID
FamUnion = Null
End If
FamUnion = (FamUnion + ", ") & Fam
UnionStr2 = FamUnion
End Function 

Оценка скорости: такая же, как и в случае 1.
Замечание: чтобы снять предположение о не пустых фамилиях можно (чтобы избежать лишних запятых) использовать в более тяжеловесную конструкцию.
В функциях место строки: 
FamUnion = (FamUnion + ", ") & Fam 
следует писать:
FamUnion = IIf (IsNull(FamUnion), Fam, FamUnion & (", " + Fam))

Случай 3. Tab1 таблица или запрос. Предположений о сортированности по ID и о пустых фамилиях нет.
Предположение: нет повторяющихся пар: ID, Fam.

В этом случае необходима промежуточная сортировка Tab1 по ID.

Текст промежуточного запроса Tab1Sort для сортировки Tab1:
Select DISTINCT ID, Fam FROM Tab1 ORDER BY ID, Fam;

Текст запроса TabUnion3:
Select ID, Last(UnionStr2(ID,Fam)) AS FamUnion 
FROM Tab1Sort 
WHERE IsEmpty(UnionStr2())
GROUP BY ID;

Здесь применяется та же функция, что и в случае 2.

Оценка скорости: оценка ухудшается из-за применения сортировки. Известно, что сортировку быстрее, чем C*n*log(n) сделать нельзя. Обычно используют сортировку методом Шелла, которая имеет оценку C*n*log(n)^2. Эта же оценка является оценкой быстродействия в данном случае. Быстрее, очевидно, сделать нельзя.
Замечание: в промежуточной сортировке используется предикат DISTINCT. Он превращает запрос Tab1Sort в статический. Без этого метод неработоспособен. Но этот же предикат удаляет повторяющиеся пары ID, Fam. Поэтому необходимо указанное выше предположение.

Случай 4. Tab1 таблица или запрос. Никаких дополнительных предположений нет.

Для применения метода слияния из случая 3 необходимо все строки Tab1 сделать уникальными.
Для этого используем нумерацию строк запроса, изложенную в статье «Нумерация строк запроса. Новый подход». 

Текст промежуточного запроса Tab1Num для нумерации Tab1:
Select DISTINCT Numeration(ID) As Num, ID, Fam
FROM Tab1
WHERE Numeration()=0;

Описание функции Numeration дано в статье, указанной выше.

Текст промежуточного запроса Tab1SortNum для сортировки Tab1Num:
Select DISTINCT ID, Fam, Num FROM Tab1Num ORDER BY ID, Fam;

И, наконец, текст запроса TabUnion4:
Select ID, Last(UnionStr2(ID,Fam)) AS FamUnion 
FROM Tab1SortNum
WHERE IsEmpty(UnionStr2())
GROUP BY ID;

Здесь применяется та же функция, что и в случае 2.

Оценка скорости: оценка скорости та же, что и в случае 3, так как нумерация имеет оценку C*n.

Решение поставленной задачи завершено.

Другой вариант постановки задачи.
Предположения о Tab1 остаются прежними.
Теперь требуется заполнить пустую таблицу Tab2, содержащую поля ID и FamUnion значениями, описанными в основной задаче.

Метод 1. Очевидный.
Формируем запрос TabUnion одним из способов, указанных выше.
Затем записываем его результат в Tab2.

Метод 2. Заполнение таблицы Tab2 с помощью Recordset.
Это можно сделать с помощью следующей функции:

Public Function UnionStr3()
Dim R As Recordset, W As Recordset
Dim IDOld, FamUnion

Set R = CurrentDb.OpenRecordset("SELECT * FROM Tab1 ORDER BY ID,Fam")
If R.EOF Then Exit Function

Set W = CurrentDb.OpenRecordset("Tab2")

Do
NewID:
IDOld = R!ID
FamUnion = Null

Union:
FamUnion = (FamUnion + ", ") & R!Fam
R.MoveNext

If R.EOF Then GoTo WriteUnion
If IDOld <> R!ID Then

WriteUnion:
W.AddNew
W!ID = IDOld
W!FamUnion = FamUnion
W.Update
Else
GoTo Union
End If
If Not R.EOF Then GoTo NewID
Exit Do
Loop
End Function 

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


Метод 3. Заполнение таблицы при помощи запросов (по Митину).
Ссылка: http://c85.cemi.rssi.ru/Access/AnsPointDetail.idc?QID=14147

Оригинальный и неочевидный метод. 
Выполняется с помощью двух запросов.
1. Запись в Tab2 уникальных ID без фамилий.
Текст запроса WriteID:
INSERT INTO Tab2 (ID) Select DISTINCT ID FROM Tab1;

2. Запись списков фамилий.
Текст запроса TabUnion5:
UPDATE Tab2 INNER JOIN Tab1 On Tab2.ID = Tab1.ID 
Set Tab2.FamUnion = ([Tab2].[FamUnion]+", ") & [Tab1].[Fam];

Оценка скорости: по-видимому, работает быстрее метода 1 за счет отсутствия вызова специальных функций.
Недостаток: "Однако в T-SQL это непрокатывает" (Митин).


Общий недостаток всех методов: при большом объеме данных все методы заполнения Tab2 работают достаточно долго.
Если результат (список фамилий) используется часто, то лучше Tab2 сделать постоянной таблицей в базе общего доступа. Далее корректировать ее при изменении Tab1. Так как одиночная корректировка Tab1 меняет только один список в Tab2, то при этом объем работы будет мал и выполнится быстро.

Реализация для базы Access: в форме, в которой можно изменить Tab1 следует на события создания/измения/удаления записи молча проводить синхронные изменения в Tab2.

Собственно такую же рекомендацию для MS SQL дает и Митин: "Я в общем то для обеспечения максимальной производительности остановился на решении, когда на триггерах поддерживается перечень упаковок в основной табл. при изменении записей в табл. с упаковками." 
 


Ваше имя:

Пароль:

Цитировать: [quote][/quote] Код: [code][/code]
Жирный: [b][/b] Наклонный: [i][/i]
URL: [url][/url] 

Сообщение:

 Размер файла не более 50 Кбт. Большие файлы можно размещать на www.slil.ru

Прикрепить:

 

Для вставки смайлов в текст щелкните по значку.