简体   繁体   English

从单个 SQL 查询中获取两个不同的值

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

Is there a way to simplify/optimise this mysql/mariadb query?有没有办法简化/优化这个 mysql/mariadb 查询? Ultimately I need two individual pieces of data from a single query: the latest transaction name and sum of all transaction payment amounts.最终,我需要来自单个查询的两条单独的数据:最新的交易名称和所有交易支付金额的总和。

This works but is ugly because it repeats the JOINS and WHERE clauses:这可行但很难看,因为它重复了 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;

I thought something like this would work but it doesn't.我认为这样的事情会起作用,但事实并非如此。 The name given is arbitrary and not the first according to the ORDER BY:给定的名称是任意的,而不是根据 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;

Edit:编辑:

Example data (NOTE: example has been simplified):示例数据(注意:示例已被简化):

tabBank Transaction Payments 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          |

tabBank Transaction tab银行交易

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

Required result: (60.00, doc3)所需结果:(60.00,doc3)

mariadb version: 10.2.27 mariadb 版本:10.2.27

We can try to use ROW_NUMBER & SUM window functions to make it.我们可以尝试使用ROW_NUMBER & SUM窗口函数来实现。

ROW_NUMBER get the lastest row of name by bt.date desc ROW_NUMBER通过bt.date desc获取 name 的最后一行

OVER clause is essential to window functions, that perform calculations based on a set of records and PARTITION BY defines the groups into which the rows are divided. OVER子句对于窗口函数是必不可少的,它基于一组记录执行计算,并且PARTITION BY定义了行被划分到的组。

More detail we can see Window Function Concepts and Syntax更多细节我们可以看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 sqlfiddle

Thanks to D-Shih for the suggestion and intro to window functions which I didn't know existed.感谢 D-Shih 对我不知道存在的窗口功能的建议和介绍。 I simplified and ended up with this.我简化并结束了这个。

For other scenarios where you need more than one result row due to partitioning, the ROW_NUMBER() will be required.对于由于分区而需要多个结果行的其他情况,将需要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.

相关问题 从SQL中的单个表获取相同属性的两个不同值 - Getting two different values for same atribute from a single table in SQL 使用SQL查询从单列设置两个列值 - Setting two column values from Single Column using sql query SQL查询两个不同查询中的行值 - SQL query for row values that are in two different queries 如何仅使用一个查询从另一个表中选择两个不同的值? - How can I select two different values from another table using only a single query? 试图在 sql 的同一查询中从两个不同的表中获取每个导演的姓名、姓氏和电影数量的列表 - Trying to take a list of the name, surname and number of movies from each director in the same query in sql, from two different tables 与两列连接,并通过单个sql查询从其外键获取字段值 - join with two columns and get field values from their foreign key with single sql query 如何从 SQL Server 中不同行的列中取值? - How to take not values from column of different rows in SQL Server? 我需要通过单个查询将值插入两个不同的表中 - i need to insert values into two different table with single query 如何在单个查询中将两个不同的数组值插入表中 - How to insert two different array values into a table in a single query SQL中如何将两个不同查询的结果组合成一个查询 - How to combine the results of two different queries into a single query in SQL
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM