簡體   English   中英

從單個 SQL 查詢中獲取兩個不同的值

[英]Take two different values from a single SQL query

有沒有辦法簡化/優化這個 mysql/mariadb 查詢? 最終,我需要來自單個查詢的兩條單獨的數據:最新的交易名稱和所有交易支付金額的總和。

這可行但很難看,因為它重復了 JOINS 和 WHERE 子句:

    SELECT
        SUM(btp.allocated_amount),
        (
        SELECT
            bt.name
        FROM
            `tabBank Transaction Payments` as btp
        LEFT JOIN
            `tabBank Transaction` bt ON bt.name=btp.parent
        WHERE
            btp.payment_document = 'Journal Entry'
        AND
            bt.docstatus = 1
        ORDER BY
            bt.date desc
        LIMIT 1
        ) AS name
        FROM
            `tabBank Transaction Payments` as btp
        LEFT JOIN
            `tabBank Transaction` bt ON bt.name=btp.parent
        WHERE
            btp.payment_document = 'Journal Entry'
        AND
            bt.docstatus = 1;

我認為這樣的事情會起作用,但事實並非如此。 給定的名稱是任意的,而不是根據 ORDER BY 的第一個名稱:

        SELECT
        (SELECT SUM(allocated_amount)),
        (SELECT name LIMIT 1)
        FROM
        (
        SELECT
            btp.allocated_amount,
            bt.name
        FROM
            `tabBank Transaction Payments` as btp
        LEFT JOIN
            `tabBank Transaction` bt ON bt.name=btp.parent
        WHERE
            btp.payment_document = 'Journal Entry'
        AND
            bt.docstatus = 1
        ORDER BY
            bt.date desc
        ) AS temp;

編輯:

示例數據(注意:示例已被簡化):

tab銀行交易付款

| parent | payment_document | allocated_amount |
------------------------------------------------
| doc1   | Journal Entry    | 10.00            |
| doc1   | Journal Entry20  | 4000.00          |
| doc2   | Journal Entry    | 20.00            |
| doc2   | Journal Entry20  | 5000.00          |
| doc3   | Journal Entry    | 30.00            |
| doc3   | Journal Entry20  | 6000.00          |

tab銀行交易

| name | date       | docstatus |
---------------------------------
| doc1 | 2022-01-01 | 1         |
| doc2 | 2022-02-01 | 1         |
| doc3 | 2022-03-01 | 1         |

所需結果:(60.00,doc3)

mariadb 版本:10.2.27

我們可以嘗試使用ROW_NUMBER & SUM窗口函數來實現。

ROW_NUMBER通過bt.date desc獲取 name 的最后一行

OVER子句對於窗口函數是必不可少的,它基於一組記錄執行計算,並且PARTITION BY定義了行被划分到的組。

更多細節我們可以看Window Function Concepts and Syntax

SELECT total_allocated_amount,name
FROM (
    SELECT
        SUM(btp.allocated_amount) OVER() total_allocated_amount,
        ROW_NUMBER() OVER(ORDER BY bt.date desc) rn,
        bt.name
    FROM
        `tabBank Transaction Payments` as btp
    LEFT JOIN
        `tabBank Transaction` bt ON bt.name=btp.parent
    WHERE
        btp.payment_document = 'Journal Entry'
    AND
        bt.docstatus = 1
) t1
WHERE rn = 1

sqlfiddle

感謝 D-Shih 對我不知道存在的窗口功能的建議和介紹。 我簡化並結束了這個。

對於由於分區而需要多個結果行的其他情況,將需要ROW_NUMBER()

SELECT *
FROM (
    SELECT
        SUM(btp.allocated_amount) OVER() total_allocated_amount,
        FIRST_VALUE(bt.name) OVER(ORDER BY bt.date desc) latest_name
    FROM
        `tabBank Transaction Payments` as btp
    LEFT JOIN
        `tabBank Transaction` bt ON bt.name=btp.parent
    WHERE
        btp.payment_document = 'Journal Entry'
    AND
        bt.docstatus = 1
) t1
LIMIT 1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM