2017-12-19 42 views
1

실제로 개발 한 프로젝트에 대한 MySQL 쿼리 관련 문제를 해결해야합니다.SUM GROUP BY 여러 테이블에 대한 하위 쿼리

가능한 경우 여러 테이블을 통해 MySQL 결과를 얻고 싶습니다. 서브 쿼리를 시도했지만 성공하지 못했습니다. 다음은 DB 구조는 다음과 같습니다

CREATE TABLE t_meeting 
(
meeting_n    INT AUTO_INCREMENT    PRIMARY KEY, 
meeting_user_n   INT       NOT NULL, 
meeting_gremium_n  INT       NOT NULL, 
meeting_gremium_f_n  VARCHAR(100)     NOT NULL, 
meeting_pay_flat  INT       NULL, 
meeting_no_pay   INT       NULL, 
meeting_pay_methode  INT       NULL, 
meeting_pay    INT       NULL, 
meeting_date   DATE       NULL, 
meeting_date_to   DATE       NULL, 
meeting_prepare   TIME       NULL, 
meeting_duration  TIME       NULL, 
meeting_allowance  DECIMAL(9, 2)    NULL, 
meeting_expences  DECIMAL(9, 2)    NULL, 
meeting_ahv    INT       NULL 
) 

CREATE TABLE t_meeting_pay 
(
meeting_pay_n   INT AUTO_INCREMENT PRIMARY KEY, 
meeting_pay_user_n  INT       NOT NULL, 
meeting_pay_date   DATE       NULL, 
meeting_pay_paiment_date DATE       NULL, 
meeting_pay_pay_for  INT       NOT NULL, 
meeting_pay_amount  DECIMAL(9, 2) DEFAULT '0.00' NULL, 
meeting_pay_meeting_n INT       NOT NULL 
) 

CREATE TABLE t_user_pay 
(
user_pay_n  INT AUTO_INCREMENT PRIMARY KEY, 
user_pay_user_n INT   NOT NULL, 
user_pay_date DATE   NULL, 
user_pay_amount DECIMAL(9, 2) NOT NULL, 
user_pay_year INT(4)  NOT NULL #<- Container the year of the meeting_date field 
) 

CREATE TABLE t_gremium 
(
gremium_n   INT AUTO_INCREMENT PRIMARY KEY, 
gremium_name  VARCHAR(250) NULL, 
gremium_name_short VARCHAR(50)  NULL, 
gremium_address VARCHAR(250) NULL, 
gremium_zip  INT(5)   NULL, 
gremium_city  VARCHAR(100) NULL, 
gremium_sector  INT    NULL, 
gremium_branch  INT    NULL, 
gremium_lvl  INT    NULL, 
gremium_ask  INT DEFAULT '0' NULL, 
gremium_ask_usern INT    NOT NULL 
) 

CREATE TABLE t_pay_for 
(
pay_for_n INT AUTO_INCREMENT PRIMARY KEY, 
pay_for_de VARCHAR(40) NOT NULL, 
pay_for_fr VARCHAR(40) NOT NULL, 
pay_for_it VARCHAR(40) NOT NULL 
) 

표 연결

사용자가 Gremium에 속하는 모임이 있습니다

t_meeting.meeting_user_n을 -> t_user.user_n t_meeting.meeting_gremium_n -> t_gremium.gremium_n

회계 직원이 Gremium에서 결제가 시작될 때 t_meeting_pay 행을 삽입 할 수 있습니다.

t_meeting_pay.meeting_pay_meeting_n -> t_meeting.meeting_n

모든 직원이 회의를 갖고 있습니다. 그 (것)들을 위해 그들은 비용을위한 관용 및 돈을 얻는다. 이 돈은 사회로 간다. 이 모든 돈에서 직원은 최대 1000 $를 얻습니다. 총 금액은 1 년입니다. 따라서 현재 7 월에 1000 달러에 도달하면 사회는 1000 달러를 직원에게 지급합니다. 도달하지 못하면 연말에 직원이 사회에 지불 한 금액을받습니다 (예 : 600 $).

User | Year | Payed allowance | Payed expenses | Payed to user 
John | 2017 |   500.00 |   200.00 |  700.00 
John | 2018 |   400.00 |   150.00 |   0.00 

, 유료 수당 = SUM (t_meeting_pay) t_meeting_pay_pay_for = 년 (t_meeting.meeting_date) 1 GROUP

:

지금은 다음과 같은 행을 반환하는 SQL 쿼리를 작성하고 싶습니다 지불 된 경비 = SUM (t_meeting_pay) 어디 t_meeting_pay_pay_for = 2 GROUP 년 (t_meeting.meeting_date)

사용자에게 지불 = SUM (t_user_pay) GROUP BY year (t_meeting.meeting_date)

따라서 최종 결과에는 동일한 테이블의 2 개의 SUM이 있어야하지만 연도별로 그룹화 된 다른 조건, 연도별로 그룹화 된 다른 테이블의 SUM 및 사용자 데이터가 있어야합니다.

쿼리는 내가 만든 :

SELECT SUM(meeting_pay_amount) AS total, YEAR(meeting_date) AS year, 
(
    SELECT SUM(user_pay_amount) AS payed 
    FROM t_user_pay 
    WHERE user_pay_year = YEAR(meeting_date) 
    GROUP BY user_pay_year 
) AS total_payed, 
(
    SELECT SUM(meeting_pay_amount) AS payed 
    FROM t_meeting_pay 
    WHERE (1) AND meeting_pay_pay_for = 1 
    GROUP BY YEAR(meeting_date) 
) AS total_payed_a, 
(
    SELECT SUM(meeting_pay_amount) AS payed 
    FROM t_meeting_pay 
    WHERE (1) AND meeting_pay_pay_for = 2 
    GROUP BY YEAR(meeting_date) 
) AS total_payed_e, user_lname 
FROM t_meeting_pay 
LEFT JOIN t_meeting ON t_meeting_pay.meeting_pay_meeting_n = t_meeting.meeting_n 
LEFT JOIN t_user ON t_meeting.meeting_user_n = t_user.user_n 
LEFT JOIN t_user_pay ON t_user.user_n = t_user_pay.user_pay_user_n 
LEFT JOIN t_gremium ON t_meeting.meeting_gremium_n = t_gremium.gremium_n 
LEFT JOIN t_pay_for ON t_meeting_pay.meeting_pay_pay_for = t_pay_for.pay_for_n 
WHERE meeting_pay_user_n = 1 
GROUP BY year 

나는 누군가가 나를 도울 수 있기를 바랍니다. 이 쿼리는 total_payed_a 및 total_payed_e가 모든 행에서 동일한 값을 갖는 유일한 오류와 함께 작동합니다 ...

답장을 미리 보내 주셔서 감사합니다.

편집 :

SQLFiddle link

바이올린 지금 작동하지만 결과가 있어야한다 :

total | year | total_payed | total_payed_a | total_payed_e | user_lname 
1600 | 2017 |  500.00 |  600.00 |  300.00 |  Dee 
800 | 2018 |  300.00 |  1000.00 |  500.00 |  Dee 
+0

당신은 sqlfiddle –

+0

사이드 노트에이를 업데이트하십시오 수 있습니다'(1) 및 meeting_pay_pay_for = '에 대한 필요가 없습니다 2''은 "(1)"및 작은 따옴표에 대한도 필요가 없습니다 이후 이것은 숫자 필드입니다. 데이터베이스는 암시 적 변환을 수행하므로 손실 된 성능을 얻을 수 있습니다. –

+0

고르 쥬얼, 고맙습니다. –

답변

1

을 많은 작업 후 arround를, 내가 예상 된 결과를 반환하는 쿼리를 얻었다.

New SQLFiddle

검색어 :

SELECT user_ma, user_lname, user_fname, 
    YEAR(meeting_date) AS meeting_year, 
    (
    SELECT SUM(user_pay_amount) AS payed 
    FROM t_user_pay 
    WHERE user_pay_year = YEAR(meeting_date) 
    GROUP BY user_pay_year 
    ) AS total_payed_to_user, 
    (
    SELECT SUM(meeting_pay_amount) 
    FROM t_meeting_pay 
    LEFT JOIN t_meeting ON t_meeting_pay.meeting_pay_meeting_n = t_meeting.meeting_n 
    WHERE meeting_pay_pay_for = '1' AND YEAR(meeting_date) = meeting_year 
    ) AS total_payed_a, 
    (
    SELECT SUM(meeting_pay_amount) 
    FROM t_meeting_pay 
    LEFT JOIN t_meeting ON t_meeting_pay.meeting_pay_meeting_n = t_meeting.meeting_n 
    WHERE meeting_pay_pay_for = '2' AND YEAR(meeting_date) = meeting_year 
    ) AS total_payed_e, 
    (
    SELECT SUM(meeting_pay_amount) 
    FROM t_meeting_pay 
    LEFT JOIN t_meeting ON t_meeting_pay.meeting_pay_meeting_n = t_meeting.meeting_n 
    WHERE YEAR(meeting_date) = meeting_year 
    ) AS total_payed 
    FROM t_meeting_pay 
    LEFT JOIN t_meeting ON t_meeting_pay.meeting_pay_meeting_n = t_meeting.meeting_n 
    LEFT JOIN t_user ON t_meeting.meeting_user_n = t_user.user_n 
    LEFT JOIN t_user_pay ON t_user.user_n = t_user_pay.user_pay_user_n 
    LEFT JOIN t_gremium ON t_meeting.meeting_gremium_n = t_gremium.gremium_n 
    LEFT JOIN t_pay_for ON t_meeting_pay.meeting_pay_pay_for = t_pay_for.pay_for_n 
    WHERE meeting_pay_user_n = 1 
    GROUP BY meeting_year 

누군가가이 쿼리를보다 효율적으로 할 수 있는지 말해 줄래?

의견을 보내 주셔서 감사합니다.

이브