Как получить отдельные строки, которые будут иметь конкретные суммы, если будут сгруппированы - PullRequest
0 голосов
/ 29 июня 2018

База данных, которую я использую, - Firebird 2.5.

Я хочу выбрать только те данные, которые, если я суммирую столбец money, получат все строки для всех лиц, суммирующих их money > 0, а также он должен содержать строки с money = 0, если он существует для этот человек.

Пример:

select name, surname, country, money from person group by 1,2,3 having sum(money)>0

Это дает мне:

SQL Error [335544824] [42000]: Dynamic SQL Error; SQL error code = -104; Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause) [SQLState:42000, ISC error code:335544824]
  Dynamic SQL Error; SQL error code = -104; Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause) [SQLState:42000, ISC error code:335544824]
    Dynamic SQL Error
      SQL error code = -104
      Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause)

Но если я добавлю столбец money в группу, он будет работать, но он не вернет строки, содержащие money = 0:

select name, surname, country, money from person group by 1,2,3,4 having sum(money)>0

Это дает ошибку:

    SELECT stag, COMMESSA, MODELLO, linea, DATA_PROD, finiti
        FROM JAVA_PRODUTTIVITA 
    GROUP BY stag, commessa, MODELLO, linea, DATA_PROD 
    HAVING sum(finiti)>0;

но если добавить в группу finiti :

    SELECT stag, COMMESSA, MODELLO, linea, DATA_PROD, finiti
        FROM JAVA_PRODUTTIVITA 
    GROUP BY stag, commessa, MODELLO, linea, DATA_PROD, finiti 
    HAVING sum(finiti)>0;

результат:

STAG |COMMESSA |MODELLO   |LINEA |DATA_PROD           |FINITI |
-----|---------|----------|------|--------------------|-------|
18S  |00254    |S3BS01W   |L1    |2018-01-12 00:00:00 |21     |
18S  |00254    |S3BS01W   |L1    |2018-01-15 00:00:00 |56     |
18S  |00254    |S3BS01W   |L1    |2018-01-16 00:00:00 |41     |
18S  |00254    |S3BS01W   |L2    |2018-01-18 00:00:00 |58     |
18S  |00254    |S3BS01W   |L2    |2018-01-19 00:00:00 |44     |
18S  |00254    |S3BS01W   |L2    |2018-01-24 00:00:00 |16     |
18S  |00255    |S3BS01X   |L1    |2018-01-09 00:00:00 |54     |
18S  |00255    |S3BS01X   |L1    |2018-01-10 00:00:00 |56     |
18S  |00255    |S3BS01X   |L1    |2018-01-11 00:00:00 |60     |
18S  |00255    |S3BS01X   |L1    |2018-01-12 00:00:00 |40     |
18S  |00255    |S3BS01X   |L1    |2018-01-17 00:00:00 |15     |
18S  |00255    |S3BS01X   |L2    |2018-01-10 00:00:00 |70     |
18S  |00255    |S3BS01X   |L2    |2018-01-11 00:00:00 |80     |
18S  |00255    |S3BS01X   |L2    |2018-01-12 00:00:00 |90     |
18S  |00255    |S3BS01X   |L2    |2018-01-15 00:00:00 |100    |
18S  |00255    |S3BS01X   |L2    |2018-01-16 00:00:00 |70     |
18S  |00255    |S3BS01X   |L2    |2018-01-17 00:00:00 |33     |
18S  |00255    |S3BS01X   |L2    |2018-01-18 00:00:00 |19     |
18S  |00255    |S3BS01X   |L2    |2018-01-19 00:00:00 |23     |
18S  |00255    |S3BS01X   |L2    |2018-01-23 00:00:00 |5      |
18S  |00306    |MPLR16W   |L1    |2018-02-07 00:00:00 |20     |
18S  |00306    |MPLR16W   |L1    |2018-02-08 00:00:00 |47     |
18S  |00306    |MPLR16W   |L1    |2018-02-09 00:00:00 |58     |
18S  |00306    |MPLR16W   |L1    |2018-02-12 00:00:00 |96     |
18S  |00306    |MPLR16W   |L1    |2018-02-13 00:00:00 |86     |
18S  |00306    |MPLR16W   |L1    |2018-02-14 00:00:00 |32     |
18S  |00307    |MPLR16W-  |L1    |2018-02-21 00:00:00 |112    |
18S  |00307    |MPLR16W-  |L1    |2018-02-22 00:00:00 |86     |
18S  |00307    |MPLR16W-  |L1    |2018-02-23 00:00:00 |118    |
18S  |00307    |MPLR16W-  |L1    |2018-02-26 00:00:00 |102    |
18S  |00308    |MPLR16X   |L1    |2018-02-27 00:00:00 |40     |

и где-то между строк должна быть запись с finiti = 0, но это не так.

1 Ответ

0 голосов
/ 29 июня 2018

Используя ваш пример SQL, может работать следующий SQL.

Вы не указали ключ, поэтому я использовал все поля в вашей группе для внутреннего соединения.

WITH SUMMARY
AS (SELECT NAME,
           SURNAME,
           COUNTRY
    FROM PERSON
    GROUP BY 1,
        2,
        3
    HAVING SUM(MONEY) > 0)
SELECT PERSON.NAME,
       PERSON.SURNAME,
       PERSON.COUNTRY,
       PERSON.MONEY
FROM SUMMARY
INNER JOIN PERSON ON (PERSON.NAME = SUMMARY.NAME AND PERSON.SURNAME = SUMMARY.SURNAME AND PERSON.COUNTRY = SUMMARY.COUNTRY) ;
...