根据与另一个字段值相比的行总和进行选择

use*_*682 2 mysql

我有一张发票项目表。单笔交易可能导致多个借项和多个贷项共享相同的invoice_set_id,我需要将借项的总和与贷项的总和进行比较,如果 sum(debits) > sum,则将 invoice_set_id 添加到结果集(学分)。如果没有信用金额的行,它也应该添加到结果中。使用 mySQL。谢谢你的帮助。示例表和结果如下:

invoice_item_id  invoice_set_id  credit_debit  amount
62                a22             debit         15.00
63                a22             debit          8.00
64                a22             credit        23.00
65                b23             debit         44.00
66                c55             debit         15.00
67                c55             debit          2.00
67                c55             credit         8.00
Run Code Online (Sandbox Code Playgroud)

鉴于上述,结果集应该是:

invoice_set_id
b23
c55
Run Code Online (Sandbox Code Playgroud)

说明:a22是因为借方和贷方相等所以不返回,b23是因为有借方没有贷方,返回c55是因为借方和贷方的总和大于单个贷方。

我很感激这方面的任何帮助。实际查询更多,但我认为这个特殊问题是我需要帮助的全部。

Seb*_*ine 6

这是一个 UNPIVOT 问题。要获得贷方项目的总和和借方项目的总和,您可以使用 a SUMof a CASEstatement。为了证明这一点,我们首先需要一个表格:

SQL小提琴

MySQL 5.5.32 架构设置

CREATE TABLE invoice_items
    (`invoice_item_id` int, `invoice_set_id` varchar(3), `credit_debit` varchar(6), `amount` int)
;

INSERT INTO invoice_items
    (`invoice_item_id`, `invoice_set_id`, `credit_debit`, `amount`)
VALUES
    (62, 'a22', 'debit', 15.00),
    (63, 'a22', 'debit', 8.00),
    (64, 'a22', 'credit', 23.00),
    (65, 'b23', 'debit', 44.00),
    (66, 'c55', 'debit', 15.00),
    (67, 'c55', 'debit', 2.00),
    (67, 'c55', 'credit', 8.00)
;
Run Code Online (Sandbox Code Playgroud)

现在您可以组合SUMCASE喜欢这样的: 查询 1

SELECT invoice_set_id,
       SUM(CASE WHEN credit_debit = 'debit' THEN amount END) AS debit_amount,
       SUM(CASE WHEN credit_debit = 'credit' THEN amount END) AS credit_amount
  FROM invoice_items
 GROUP BY invoice_set_id;
Run Code Online (Sandbox Code Playgroud)

结果

| INVOICE_SET_ID | DEBIT_AMOUNT | CREDIT_AMOUNT |
|----------------|--------------|---------------|
|            a22 |           23 |            23 |
|            b23 |           44 |        (null) |
|            c55 |           17 |             8 |
Run Code Online (Sandbox Code Playgroud)

从这里过滤掉不需要的行是相当简单的。我们只需要在COALESCE语句中包装这两个和以NULL变成 0:

查询 2

SELECT invoice_set_id
  FROM(
    SELECT invoice_set_id,
           SUM(CASE WHEN credit_debit = 'debit' THEN amount END) AS debit_amount,
           SUM(CASE WHEN credit_debit = 'credit' THEN amount END) AS credit_amount
      FROM invoice_items
     GROUP BY invoice_set_id
  )X
WHERE COALESCE(debit_amount,0) > COALESCE(credit_amount,0);
Run Code Online (Sandbox Code Playgroud)

结果

| INVOICE_SET_ID |
|----------------|
|            b23 |
|            c55 |
Run Code Online (Sandbox Code Playgroud)

如果您的实际问题与您的示例一样简单,并且您不需要其他任何中间值,您也可以通过credit_debit在计算总和之前根据该值更改金额的符号来获得结果。那看起来像这样:

查询 3

SELECT invoice_set_id
  FROM invoice_items
 GROUP BY invoice_set_id
HAVING SUM(CASE WHEN credit_debit = 'debit' THEN amount ELSE -amount END)>0;
Run Code Online (Sandbox Code Playgroud)

结果

| INVOICE_SET_ID |
|----------------|
|            b23 |
|            c55 |
Run Code Online (Sandbox Code Playgroud)