Есть ли способ заставить Crystal Reports включать константу в условие соединения без использования объекта команды SQL? - PullRequest
4 голосов
/ 22 октября 2008

Что я хочу сделать - это внешнее соединение с таблицей, где я исключаю записи из объединенной таблицы на основе сопоставления с константой, но сохраняю записи из основной таблицы. Например:

SELECT a.id, a.other, b.baz
FROM a
LEFT OUTER JOIN b
  ON a.id  = b.id
  AND b.bar = 'foo'

Ожидаемые результаты:

    id  other       baz      
    --  ----------  -------  
    1   Has foo     Include  
    2   Has none    (null)   
    3   Has foobar  (null)   

Я не могу получить тот же результат, если поместить его в состояние фильтра. Если я использую следующее:

SELECT a.id, a.other, b.baz
FROM a
LEFT OUTER JOIN b
  ON a.id  = b.id
WHERE (b.bar IS NULL OR b.bar = 'foo')

Я получаю неправильные результаты:

    id  other     baz      
    --  --------  -------  
    1   Has foo   Include  
    2   Has none  (null)   

Где исключены записи A, которые соответствуют записи B, где bar = 'foobar'. Я не хочу этого, я хочу, чтобы A присутствовал, но B в этом случае был бы нулевым.

В таблице B будет несколько записей, которые нужно исключить, поэтому я не думаю, что смогу отфильтровать это на стороне Crystal, не потратив много времени, чтобы избежать проблем с дублированием записей из таблицы A.

Я не могу использовать объект команды SQL, поскольку стороннее приложение, из которого мы запускаем отчеты, похоже, задыхается от объектов команды SQL.

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

Я работаю с Crystal Reports XI, а именно с версией 11.0.0.895. Если это имеет значение, я работаю с базой данных Progress 9.1E04, используя драйвер ODBC для SQL-92.

Примеры таблиц и данных, использованных в примерах, могут быть созданы с помощью следующего:

CREATE TABLE a (id INTEGER, other VARCHAR(32));
CREATE TABLE b (id INTEGER, bar VARCHAR(32), baz VARCHAR(32));
insert into A (id, other) values ('1', 'Has foo');
insert into A (id, other) values ('2', 'Has none');
insert into A (id, other) values ('3', 'Has foobar');
insert into B (id, bar, baz) values ('1', 'foo', 'Include');
insert into B (id, bar, baz) values ('1', 'foobar', 'Exclude');
insert into B (id, bar, baz) values ('1', 'another', 'Exclude');
insert into B (id, bar, baz) values ('1', 'More', 'Exclude');
insert into B (id, bar, baz) values ('3', 'foobar', 'Exclude');

Ответы [ 8 ]

7 голосов
/ 08 января 2010

Crystal Reports не может генерировать этот часто используемый оператор SQL на основе его ссылок и критериев выбора отчетов. Вы должны использовать «команду» или построить представление.

Короче, Кристал отстой.

2 голосов
/ 20 ноября 2012

Является ли хранимая процедура опцией для вас? Если это так, вы можете предварительно выбрать наборы данных таким образом, не прибегая к опции команды, и вы можете импортировать хранимую процедуру, как таблицу.

Я бы предложил хранимую процедуру, которая выполняет select * from b where bar= 'foo' и присоединяется к ней, так что таблица b предварительно фильтруется, поэтому все, что вам нужно сделать, это присоединиться к другому полю соединения.

Надеюсь, это поможет.

0 голосов
/ 07 апреля 2017

Не следует добавлять условие фильтра для таблицы b с помощью b.bar is null or b.bar = 'foo', но также не следует напрямую обращаться к атрибутам из таблицы b Вы должны получить все атрибуты по условию if b.bar = 'foo' через формулу.

0 голосов
/ 05 января 2013

Мне кажется, вы не хотите принимать чьи-либо предложения, но в любом случае вот последний бросок на это. Решение, которое я использовал недавно, когда БД должна оставаться неизменной, выглядит следующим образом:

  1. Настройте сервер Tomcat, чтобы я мог запустить JSP и Hibernate.
  2. Grab Crystal сообщает о затмении
  3. Создание отчета в Crystal Reports Designer с поддельными данными на локальном БД в соответствии с тем, как я получу данные в идеальном мире
  4. Использование прохода сервлета java Перечислите каждый из псевдонимов таблицы так, чтобы в отчете данные заменялись непосредственно из POJO. Конечно, POJO могут быть полностью составлены в java, извлекая содержимое из различных таблиц db и распределяя их по своему усмотрению, часто позволяя предоставить полностью сглаженный набор данных, с которым Crystal Reports только рада работать. *
0 голосов
/ 29 апреля 2011

Добавление

(Isnull({b.bar}) OR {b.bar} = "foo")

к формуле выбора записи должно действовать так, как вы ожидаете.

** редактировать **

Пара других вещей, которые стоит попробовать:

  • Используйте другой драйвер базы данных - собственный драйвер (который избегает ODBC) может работать по-другому. Сначала я заметил это с помощью синтаксиса WITH - драйвер ODBC для SQL Server не работал, но собственный драйвер SQL Server работал.
  • Несмотря на то, что он жертвует некоторой гибкостью, вставьте запрос в команду, предполагая, что вы можете заставить сторонний продукт соответствовать. Добавлено для полноты.
0 голосов
/ 19 ноября 2008

Я вижу два решения:

a) принять наличие нескольких (ненужных) строк в B (и повторяющихся значений в A), рассчитать итоговые значения с использованием полей итогов и / или формул runnign - не простой способ, но почти всегда возможный; b) переместить B в подотчет (где вы можете легко установить фильтр) и передать необходимые значения между основным и вложенным отчетом, используя общие переменные.

Подотчеты являются мощным инструментом для решения проблем такого рода, если только вам не нужно их вкладывать (невозможно) или экспортировать отчеты в Excel (добавляет пустые строки, по крайней мере, в CR 9).

0 голосов
/ 01 ноября 2008

Не можете ли вы создать соответствующие представления в базе данных и основать свой отчет на этих представлениях? Я использую Crystal Reports на MSSQL и часто просто создаю представления, чтобы избежать подобных проблем.

0 голосов
/ 24 октября 2008

Не уверен, что вы можете сделать это в Crystal, но как насчет присоединиться к Select?

SELECT a.id, x.baz
FROM a
LEFT OUTER JOIN 
 (SELECT id, baz FROM b WHERE bar = 'foo') As x ON a.id  = x.id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...