2016-06-27 5 views
0

このmysqlビューを改善するには?同じテーブルにアクセスする2つのサブクエリを避けることはできますか?

私はそれが= d.donation_method = m.donation_method同じWHERE CLAUSEと同じテーブルjc_donation_methodに両方へのアクセスが異なるSELECT CLAUSEL 2つのサブクエリを実行する必要はないと思います。しかし、私はこれを避けるべきではありません。

donation_idは、jc_donationのプライマリキーであり、外部キーはjc_donation_methodです。 (単一寄付あたり)パーセントの手数料の% - 非継続手数料 - 量:

 
CREATE 
    OR REPLACE 
    ALGORITHM = MERGE 
    VIEW jc_donation_total AS 
SELECT 
    d.donation_method, 
    (SELECT 
     m.method_name 
    FROM 
     `jc_donation_method` m 
    WHERE 
     d.donation_method = m.donation_method 
    LIMIT 1) method_name, 
    CAST(SUM(d.donation_amount- 
    (SELECT 
     m.method_fee_nonrecurring 
    FROM 
     `jc_donation_method` m 
    WHERE 
     d.donation_method = m.donation_method 
    LIMIT 1) 
    - d.donation_amount*(
    (SELECT 
     m.method_fee_percent 
    FROM 
     `jc_donation_method` m 
    WHERE 
     d.donation_method = m.donation_method 
    LIMIT 1)) 
) as decimal(12,4)) donation_total 
FROM 
    `jc_donation` d 
LEFT JOIN 
    `jc_user` u 
ON 
    d.user_id = u.user_id 
GROUP BY 
    d.donation_method 
HAVING 
    COUNT(u.user_id) > 0 

基本的に私はdonation_methodあたりのアクティブユーザーによって行われているすべての全体的な寄付を知っていただきたいと思います。

前提条件:

 
CREATE TABLE `jc_user` (
    `user_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`user_id`) USING BTREE 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='User credentials'; 

CREATE TABLE `jc_donation_method` (
    `donation_method` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `method_name` varchar(32) NOT NULL, 
    `method_fee_percent` decimal(6,4) NOT NULL DEFAULT 0.00, 
    `method_fee_nonrecurring` decimal(5,2) NOT NULL DEFAULT 0.00, 
    PRIMARY KEY (`donation_method`) USING BTREE, 
    UNIQUE KEY `method_name` (`method_name`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Donation methods and fees'; 

INSERT INTO 
    `jc_donation_method` (`donation_method`, `method_name`, 
    `method_fee_percent`, `method_fee_nonrecurring`) 
VALUES 
    (NULL, 'Transfer',0.000,0.00), 
    (NULL, 'PayPal',0.0190,0.35); 

CREATE TABLE `jc_donation` (
    `donation_id` int(10) NOT NULL AUTO_INCREMENT, 
    `user_id` int(10) UNSIGNED NOT NULL, 
    `donation_method` int(10) UNSIGNED NOT NULL DEFAULT '1', 
    `donation_amount` decimal(12,4) NOT NULL, 
    PRIMARY KEY (`donation_id`) USING BTREE, 
    FOREIGN KEY (user_id) REFERENCES jc_user(user_id), 
    FOREIGN KEY (donation_method) REFERENCES jc_donation_method(donation_method) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Donations'; 
+0

通常、私は「INNER JOIN」について話していますが、その軟膏のフライはネストされたクエリのそれぞれに「LIMIT 1」句のようです。 ##私の個人的な結論は、(私はSeuss '* Green EggsとHam *を引用しています): "私はこの見解の匂いが好きではありません、Sam-I-Am。ロジックは* INNER JOINを使用すべきだと思うが、これは必ずアプリケーション内のどこでもこのビューのすべてのコンシューマが結果に複数の行を表示するように準備されなければならないことを意味する。 –

+0

さて、 'donation_id'ですべての寄付' jc_donations'を含むテーブルがあります。別のテーブル 'jc_user'には、すべてのユーザが格納されています。すべてのユーザーは、いくつかの寄付をすることができます。 すべての寄付は、銀行振込またはpaypalのような 'jc_donation_method'のさまざまな方法(' donation_method)に基づいています。支払いサイトのほとんどは、いくつかの料金を請求します。すべての移転またはパーセンテージ費用についての非経常費用。それらのいくつかの両方(ペイパル)。 このビューは、donation_methodごとの料金の後の総所得を表します。 – EaglePsyX

+0

内部結合が正しい方法であり、1つのレコードだけが来るように、あなたが望むレベルまで集約するサブクラスに内部結合したいと思うようです。 – Jeff

答えて

1

私は私の最初のコメントで述べたように、ユーザが関連している理由は、私はわかりませんが、これは、あなたが望む結果を得るための最も簡単なクエリする必要があります:

SELECT m.donation_method, m.method_name 
    , CAST(
     d.donation_amount 
     - m.method_fee_nonrecurring 
     - (d.donation_amount * m.method_fee_percent) 
    AS DECIMAL(12, 4)) donation_total 
FROM jc_donation_method AS m 
INNER JOIN jc_donation AS d 
ON m.donation_method = d.donation_method 
GROUP BY m.donation_method 
; 

下のバージョンは、元のようなユーザーを考慮する必要があります。

SELECT m.donation_method, m.method_name 
    , CAST(
     d.donation_amount 
     - m.method_fee_nonrecurring 
     - (d.donation_amount * m.method_fee_percent) 
    AS DECIMAL(12, 4)) donation_total 
FROM jc_donation_method AS m 
INNER JOIN jc_donation AS d 
INNER JOIN jc_user AS u ON d.user_id = u.user_id 
ON m.donation_method = d.donation_method 
GROUP BY m.donation_method 
; 
+0

ありがとうございました!あなたはまったく正しい!私は、ユーザー(支払い)に不信を抱いているが、代わりに寄付テーブルで 'donation_canceled 'を使用している場合にユーザーを退席させた=) – EaglePsyX

関連する問題