Транспонирование таблицы
Добавлено: 26 июн 2006, 16:02
Есть ли способ динамически формировать запрос, который бы имел в виде столбцов значения полей одной таблицы, а строками были бы значения из другой таблицы?
Колонки - клиенты, строки - товары, пересечение - сумма или количество. Да сколько угодно примеров.А зачем вам такое извращение? Приведите пример с обоснованием.
Это однозначно отчёт. Или OLAP, что несколько выходит за рамки Firebird/Interbase.zenja писал(а):Есть надобность (у заказчика) видеть набор данных, в котором после каждой фамилии идет количество акций разных типов...
Да, это скорее OLAP, т.к. с отчетом все более менее ясно.WildSery писал(а):Это однозначно отчёт. Или OLAP, что несколько выходит за рамки Firebird/Interbase.zenja писал(а):Есть надобность (у заказчика) видеть набор данных, в котором после каждой фамилии идет количество акций разных типов...
Так у тебя еще количество типов разное? Получается, еще саму форму отчета динамически строишь... Сходу я бы сделал так: два цикла в двух датасетах по эмитентам и типам акций. В третий передаешь в качестве параметров условия отбора по эмитенту и типу. На выходе получаешь количество акций. Полученные данные скармливаешь отчету. Коряво конечно, есть варианты и лучше, но надо думать.zenja писал(а):Есть надобность (у заказчика) видеть набор данных, в котором после каждой фамилии идет количество акций разных типов, т.е. набор данных должен выглядеть так:
ФИО, кол-во акций типа 1, ... кол-во акций типа N
Есть таблицы владельцев, акций и привязки акций. Здесь N - количество типов акций у эмитента.
Код: Выделить всё
DataSet.SelectSQL.Add('SELECT');
DataSet.SelectSQL.Add(' C.ID,');
while not SQLTypeAction.EOF do
DataSet.SelectSQL.Add(' (SELECT COUNT(*) FROM ACT_CLIENT WHERE (ID_CLIENT = C.ID_CLIENT) AND (ID_TYPE_ACTION = ' + SQLTypeAction.FieldByName('ID').AsString + ')),';
DataSet.SelectSQL.Add(' C.NAME');
DataSet.SelectSQL.Add('FROM');
DataSet.SelectSQL.Add(' CLIENT C');
DataSet.SelectSQL.Add('ORDER BY');
DataSet.SelectSQL.Add(' NAME');
не надо ужасных идей или фантазий. процедура не может возвращать произвольный набор столбцов.Ну или динамический SQL в процедуре.
Никогда не применяй решения, работоспособность которых зависит от подобных факторов. Вон, сам Б. Гейтс заявлял, что "640 кб хватит всем". И где теперь эти 640 кб? Может, пройдет пару лет, и 10 мало будет. Потом 20... Тогда как код через дин. формирование select'а будет работать всегда.zenja писал(а):Конечно же не может. Но если описать выходных переменных штук эдак 10 (из расчета, что самое большое количество динамических столбцов будет 8-9), то очень даже можно.
Только не очень красиво...
Зато может динамическая процедура aka EXECUTE BLOCK в FB 2.zenja писал(а):Конечно же не может.
Код: Выделить всё
Parameter(
CODE VARCHAR(25),
NAME VARCHAR(100))
Account_Parameter(
ID_Account INT,
Parameter VARCHAR(25), --ссылка на Parameter.Code
Float_Value Float)
Код: Выделить всё
DECLARE @Par NVARCHAR(MAX), @Col NVARCHAR(MAX)
SET @Par = N''
SET @Col = N''
DECLARE @Sql NVARCHAR(MAX)
SELECT
@Col = @Col + N',SUM(CASE WHEN Parameter=''' + Code + N''' THEN Float_Value END) AS ['+Name+N']',
@Par = @Par + N''''+ Code + N''','
FROM Parameter
WHERE ...
SET @Par = LEFT(@Par, LEN(@Par) - 1)
SET @Sql = N'SELECT ID_Account,'+@Col+
N'FROM Account_Parameter
WHERE Parameter IN (' + @Par+ N')
GROUP BY ID_Account'
EXEC SP_EXECUTESQL @SQL