Хранимая процедура Firebird для конкатенации всех значений полей от нескольких строк

Если у вас есть все ваши данные в одном кадре данных, df, вы можете сделать следующее:

grp_by_cols = ['Supplier', 'ID', 'Grp']
all_cols = grp_by_cols + ['Unit']
res_df = df.assign(first_unit=lambda df: df.loc[:, all_cols]
                                           .groupby(grp_by_cols)
                                           .transform('first'))\
           .assign(incorrect=lambda df: df['Unit'] == df['first_unit'])\
           .assign(incorrect=lambda df: df.loc[:, grp_by_cols + ['incorrect']])\
                                          .groupby(grp_by_cols)
                                          .transform(np.any))

При первом вызове assign добавляется один новый столбец (называемый 'first_unit'. ]) это первое значение «Единицы» для каждой группы Поставщика / ID / Grp (см. grp_by_cols).

Второй вызов assign добавляет столбец с именем 'incorrect', то есть True, когда 'Unit' не равен 'first_unit'. Третий и последний вызов assign заменяет этот столбец на True, если любых строк в этой группе равны True. Вы можете удалить это, если это не то, что вы хотите.

Затем, если вы хотите посмотреть на результаты для одного поставщика, вы можете сделать что-то вроде:

res_df.query('Supplier = "Authentic Brands Group"')
5
задан bluish 18 October 2011 в 08:04
поделиться

2 ответа

Следующая процедура делает то, что Вы описываете:

SET TERM !!;
CREATE PROCEDURE concat_names
  RETURNS (concat VARCHAR(2000))
AS
DECLARE VARIABLE name VARCHAR(100);
BEGIN
  concat = '';
  FOR SELECT first_name || ' ' || last_name FROM employee INTO :name
  DO BEGIN
    concat = concat || name || ', ';
  END
END!!
SET TERM ;!!
EXECUTE PROCEDURE concat_names;

Но я подвергаю сомнению мудрость этого решения. Как Вы знаете, что VARCHAR достаточно длинен для всех строк в Вашем желаемом наборе данных?

Это намного легче и более безопасно выполнить запрос для возврата результата строке приложения строкой. Каждый язык прикладного программирования имеет методы для конкатенации строк, но что еще более важно у них есть более гибкие методы для управления ростом данных.

Между прочим, "диалект" в Firebird и InterBase относится к режиму эмуляции, который был представлен так, чтобы приложения, разработанные для InterBase 5.x, могли работать с более поздними версиями InterBase и Firebird. Это было почти десять лет назад, и AFAIK, там не потребность сегодня для использования чего-либо ниже, чем диалект 3.

5
ответ дан 14 December 2019 в 19:30
поделиться

Необходимо протестировать на нулевые значения при конкатенации вот пример для двух полей и разделителя между ними:

    CREATE PROCEDURE CONCAT(
    F1 VARCHAR(385),
    F2 VARCHAR(385),
    SEPARATOR VARCHAR(10))
RETURNS (
    RESULT VARCHAR(780))
AS
begin

  if ((:f1 is not null) and (:f1 <> '')) then
    result = :f1;

  if ((:f2 is not null) and (:f2 <> '')) then
    if ((result is not null) and (result <> '')) then
      begin
        if ((:separator is not null) and (separator <> '')) then
          result = result||separator||f2;
        else
          result = result||f2;
      end
    else
      result = f2;

  suspend;
end
0
ответ дан 14 December 2019 в 19:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: