SQL-запрос для расчета агрегированного значения только для столбцов числового типа с использованием звездочки - PullRequest
0 голосов
/ 13 октября 2018

Предположим, у меня есть таблица с разнородными столбцами (varchar, int и т. Д.).

+-------+----+----+----+
| Nme   | Py | cm | Mt |
+-------+----+----+----+
| johny | 68 | 70 | 66 |
| Harry | 86 | 76 | 90 |
| johny | 18 | 72 | 66 |
+-------+----+----+----+

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

Что мне нужно, но в общей форме

SELECT SUM(Py), SUM(cm), SUM(Mt) FROM table GROUP BY NME;

На что-то вроде:

SELECT SUM(*) FROM table WHERE <COLUMNTYPE(INT)> GROUP BY NME;

Есть ли способ обойти или это невозможно в SQL?

Ответы [ 3 ]

0 голосов
/ 13 октября 2018

Если вы хотите попробовать динамический sql для этого?

Вот пример фрагмента для MySql:

-- Adding a test table
drop table if exists test_dynamic;
create table test_dynamic (ID int auto_increment primary key, Nme varchar(30), Py int, Cm int, Mt int);

-- Some sample data
insert into test_dynamic (Nme, Py, Cm, Mt) values
('johny',68,70,66),
('Harry',86,76,90),
('johny',18,72,66);

-- Build a string for the aggregations
set @Sums := (select group_concat(concat(' SUM(', column_name, ') as ', column_name)) as sums
from information_schema.columns
where table_schema = database() 
and table_name = 'test_dynamic'
and data_type = 'int'
and column_key != 'PRI');

-- Stick it to a string for the select
set @DynSql := concat('select 
 Nme, 
', @Sums, '
from test_dynamic
group by Nme
order by Nme');

-- Run the created dynamic sql string
PREPARE stmt FROM @DynSql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Возвращает:

Nme     Py  Cm  Mt
----    --  --  --
Harry   86  76  90
johny   86  142 132
0 голосов
/ 13 октября 2018

Этот блок кода работает на сервере sql

Ни один оператор SQL не может выполнить эту задачу.

BEGIN
    DECLARE @ColumnSUM nvarchar(max) = 'NME'

    SELECT @ColumnSUM += ', SUM(' + COLUMN_NAME + ') ' + COLUMN_NAME
      FROM INFORMATION_SCHEMA.COLUMNS
     WHERE TABLE_NAME = 'test_dynamic'
       AND DATA_TYPE = 'int'
       AND COLUMN_NAME != 'ID'

    EXEC('SELECT ' + @ColumnSUM + ' FROM test_dynamic GROUP BY NME ORDER BY NME')
END 

Результат:

NME     Py  Cm  Mt
---     --  --  --
Harry   86  76  90
johny   86  142 132
0 голосов
/ 13 октября 2018

Нет такого.Вы, кажется, неправильно понимаете, как использовать SQL.Я думаю, что вам нужна таблица, которая "разворачивает" ваши данные.Что-то вроде:

create table personValues (
    personValues int auto_increment primary key,
    person varchar(255),
    value_type varchar(255),
    value int
);

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

select value_type, sum(value)
from personValues
group by value_type;

Если вам необходимо повернуть это в одну строку, у вас есть два варианта:

  • Сводка с использованием динамического SQL.
  • Использование group_concat() для создания длинной строки.
...