Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在联接表中只匹配每条记录一次_Sql_Postgresql - Fatal编程技术网

Sql 在联接表中只匹配每条记录一次

Sql 在联接表中只匹配每条记录一次,sql,postgresql,Sql,Postgresql,我有两张桌子。第一个inv包含发票记录,第二个包含付款。我想通过inv\u amount和inv\u date匹配inv\u表中的付款。同一天可能有多张相同金额的发票,也可能有多张相同金额的付款 付款应与第一张匹配发票匹配,且每笔付款只能匹配一次 这是我的数据: 表inv inv_id | inv_amount | inv_date | inv_number --------+------------+------------+------------ 1 |

我有两张桌子。第一个
inv
包含发票记录,第二个
包含付款
。我想通过
inv\u amount
inv\u date
匹配
inv\u表中的付款。同一天可能有多张相同金额的发票,也可能有多张相同金额的付款

付款应与第一张匹配发票匹配,且每笔付款只能匹配一次

这是我的数据:

inv

 inv_id | inv_amount |  inv_date  | inv_number
--------+------------+------------+------------
      1 |         10 | 2018-01-01 |          1
      2 |         16 | 2018-01-01 |          1
      3 |         12 | 2018-02-02 |          2
      4 |         14 | 2018-02-03 |          3
      5 |         19 | 2018-02-04 |          3
      6 |         19 | 2018-02-04 |          5
      7 |          5 | 2018-02-04 |          6
      8 |         40 | 2018-02-04 |          7
      9 |         19 | 2018-02-04 |          8
     10 |         19 | 2018-02-05 |          9
     11 |         20 | 2018-02-05 |         10
     12 |         20 | 2018-02-07 |         11
pay

 pay_id | pay_amount |  pay_date
--------+------------+------------
      1 |         10 | 2018-01-01
      2 |         12 | 2018-02-02
      4 |         19 | 2018-02-04
      3 |         14 | 2018-02-03
      5 |          5 | 2018-02-04
      6 |         19 | 2018-02-04
      7 |         19 | 2018-02-05
      8 |         20 | 2018-02-07
我的问题是:

 SELECT DISTINCT ON (inv.inv_id) inv.inv_id,
    inv.inv_amount,
    inv.inv_date,
    inv.inv_number,
    pay.pay_id
   FROM ("2016".pay
     RIGHT JOIN "2016".inv ON (((pay.pay_amount = inv.inv_amount) AND (pay.pay_date = inv.inv_date))))
  ORDER BY inv.inv_id
导致:

 inv_id | inv_amount |  inv_date  | inv_number | pay_id
--------+------------+------------+------------+--------
      1 |         10 | 2018-01-01 |          1 |      1
      2 |         16 | 2018-01-01 |          1 |
      3 |         12 | 2018-02-02 |          2 |      2
      4 |         14 | 2018-02-03 |          3 |      3
      5 |         19 | 2018-02-04 |          3 |      4
      6 |         19 | 2018-02-04 |          5 |      4
      7 |          5 | 2018-02-04 |          6 |      5
      8 |         40 | 2018-02-04 |          7 |
      9 |         19 | 2018-02-04 |          8 |      6
     10 |         19 | 2018-02-05 |          9 |      7
     11 |         20 | 2018-02-05 |         10 |
     12 |         20 | 2018-02-07 |         11 |      8
记录
inv\u id=6
不应与
pay\u id=4
匹配,因为这意味着payment 4插入了两次

预期结果:

inv_id | inv_amount |  inv_date  | inv_number | pay_id
--------+------------+------------+------------+--------
      1 |         10 | 2018-01-01 |          1 |      1
      2 |         16 | 2018-01-01 |          1 |
      3 |         12 | 2018-02-02 |          2 |      2
      4 |         14 | 2018-02-03 |          3 |      3
      5 |         19 | 2018-02-04 |          3 |      4
      6 |         19 | 2018-02-04 |          5 |        <- should be empty**
      7 |          5 | 2018-02-04 |          6 |      5
      8 |         40 | 2018-02-04 |          7 |
      9 |         19 | 2018-02-04 |          8 |      6
     10 |         19 | 2018-02-05 |          9 |      7
     11 |         20 | 2018-02-05 |         10 |
     12 |         20 | 2018-02-07 |         11 |      8
inv_id | inv_金额| inv_日期| inv_编号| pay_id
--------+------------+------------+------------+--------
1 |         10 | 2018-01-01 |          1 |      1
2 |         16 | 2018-01-01 |          1 |
3 |         12 | 2018-02-02 |          2 |      2
4 |         14 | 2018-02-03 |          3 |      3
5 |         19 | 2018-02-04 |          3 |      4

6 | 19 | 2018-02-04 | 5 |看了这个例子后,我想我有一个问题要问你:

WITH payments_cte AS (
    SELECT
        payment_id,
        payment_amount,
        payment_date,
        ROW_NUMBER() OVER (PARTITION BY payment_amount, payment_date ORDER BY payment_id) AS payment_row
    FROM payments
), invoices_cte AS (
    SELECT
        invoice_id,
        invoice_amount,
        invoice_date,
        invoice_number,
        ROW_NUMBER() OVER (PARTITION BY invoice_amount, invoice_date ORDER BY invoice_id) AS invoice_row
    FROM invoices
)
SELECT invoice_id, invoice_amount, invoice_date, invoice_number, payment_id
FROM invoices_cte
LEFT JOIN payments_cte
    ON payment_amount = invoice_amount
    AND payment_date = invoice_date
    AND payment_row = invoice_row
ORDER BY invoice_id, payment_id

谢谢你的回答和编辑。我只是看到数据顺序不对。我更新了帖子和sqlfiddle。但是,您的查询中缺少记录。没有inv_id 3、6和12。我用所需的结果更新了帖子。@user2626227我已经更新了查询,我想这正是您想要的:)谢谢您更新了查询。但是,通过此查询,pay_id 4与发票_id 6匹配,而不是与第一种可能的发票_id 5匹配。我插入了一些真实数据并使用了您的查询。sqlfiddle.com/#!17/72ee1/1。正如您所看到的,付款编号6201不是它应该在的地方,付款编号6212和6218完全不正常。我想可能我试图用sql查询做的是不可能的。付款应自上而下地将日期和金额记录与发票匹配,并在金额和日期匹配的位置随机匹配。使用常用的表表达式(带查询)可能仍然可以,但这些表达式编写起来有点困难,而且我的时间有点紧。@leu我已再次更新了答案,通过唯一地比较所有副本,这也应该考虑所有边缘情况。