我有一个有趣的问题 - 我需要与JOIN语句完全相反。
我有一张名为发票的表,另一张名为付款的表。我想按顺序检索没有附加任何付款的发票,但后面跟着附有付款的行。
发票表包含以下字段:
付款表包含以下字段:
并非所有付款都是全额付款,因此每张发票都可以附加多笔付款。
我希望未付款的发票首先出现(不付款),然后是部分付款但未满的发票,然后是完全付款的发票。
我希望执行此操作而不必运行单独的SQL查询,如果可以的话 - 我宁愿它是一个查询,所以我可以吐出一次。有任何想法吗?
- 更新 -
根据DCP的回答,我更新了查询方法。我有它工作,直到我需要添加JOIN语句也按我的sub_to_inv表排序,如下所示:
id订阅发票 0 12 18 1 13 18 2 14 19
等。
基于此,我提出了这个问题(在页面的最后限制中添加了LIMIT。)
SELECT i.id AS id, i.modify_date as modify_date, s.subscription as subscriptionid, 0 paidratio FROM invoices i
LEFT JOIN sub_to_inv s ON i.id=s.invoice
WHERE NOT EXISTS (SELECT id FROM payments p WHERE p.invoice=i.id) AND i.corporation='3' AND i.payer=1
UNION ALL
SELECT i.id AS id, i.modify_date as modify_date, s.subscription as subscriptionid, p.paid/i.total AS paidratio FROM invoices i,
(SELECT p.invoice, sum(amount) AS paid FROM payments p GROUP BY p.invoice) p
LEFT JOIN sub_to_inv s ON i.id=s.invoice
WHERE p.invoice=i.id AND i.corporation='3' AND i.payer=1
AND p.paid UNION ALL
SELECT i.id AS id, i.modify_date as modify_date, s.subscription as subscriptionid, p.paid/i.total AS paitratio FROM invoices i,
(SELECT p.invoice, sum(amount) AS paid FROM payments p WHERE p.invoice=id GROUP BY p.invoice) p
LEFT JOIN sub_to_inv s ON i.id=s.invoice
WHERE p.invoice = i.id AND i.corporation='3' AND i.payer=1
AND p.paid=i.total
ORDER BY paidratio DESC, modify_date DESC, subscriptionid ASC LIMIT 0,40
我收到“i.id column not found”错误,但我没有收到。在最终通过UNION语句组合的每个语句块上,我指定invoices i
以确保i.id引用发票的id。 tab.e
答案 0 :(得分:2)
如果我假设你有invoice_details
表,其中包含金额:
SELECT i.id as invoiceid,
case
when (select sum(amount) from payments where invoiceid = i.id group by invoiceid) = d.amount
then 3
when (select sum(amount) from payments where invoiceid = i.id group by invoiceid) < d.amount
then 2
else 1
end
as paidstatus
FROM invoices i
INNER JOIN invoice_details d
ON i.id = d.invoiceid
LEFT JOIN payments p
ON i.id = p.invoiceid
GROUP BY i.id, d.amount
ORDER BY paidstatus
paystatus:
1 =无薪
2 =部分支付的
3 =付费
答案 1 :(得分:2)
您没有告诉我们如何确定总发票金额,但我假设您的发票表上有一些字段。在下面的例子中,我假设它叫做TOT_AMT。
这种方法背后的想法是我们在三个单独的步骤中获取数据,并且我们使用UNION ALL将三个部分粘合在一起。我们使用名为PAY_TYPE的伪列来获得您想要的订单,即先付款的发票,然后是部分付款的发票,最后是全额付款的发票。
下面显示了一个完整的工作示例(我使用了Oracle,但我认为您可以轻松地将其调整为MySQL)。
CREATE TABLE invoices (ID number, tot_amt NUMBER);
CREATE TABLE payments (ID NUMBER, invoice_id NUMBER, amount NUMBER);
INSERT INTO invoices VALUES (1,100);
INSERT INTO invoices VALUES (2,200);
INSERT INTO invoices VALUES (3,300);
INSERT INTO payments VALUES (1,1,20);
INSERT INTO payments VALUES (2,1,40);
INSERT INTO payments VALUES (3,3,150);
INSERT INTO payments VALUES (4,3,120);
INSERT INTO payments VALUES (5,3,30);
/* get invoices with no payments */
SELECT i.id
, i.TOT_AMT
, 0 TOT_PAID
, '0_NO_PAYMENTS' PAY_TYPE
FROM invoices i
WHERE NOT EXISTS (SELECT * FROM PAYMENTS P WHERE P.INVOICE_ID = I.ID)
UNION ALL
/* get invoices with partial payments */
SELECT i.id
, i.TOT_AMT
, p.tot_paid
, '1_PARTIALLY_PAID' PAY_TYPE
FROM invoices i
, (SELECT P.INVOICE_ID
, SUM(AMOUNT) tot_paid
FROM PAYMENTS P
GROUP BY P.INVOICE_ID) p
WHERE P.INVOICE_ID = I.ID
AND p.TOT_PAID < i.TOT_AMT
UNION ALL
/* get invoices that are fully paid */
SELECT i.id
, i.TOT_AMT
, p.tot_paid
, '2_FULLY_PAID' PAY_TYPE
FROM invoices i
, (SELECT P.INVOICE_ID
, SUM(AMOUNT) tot_paid
FROM PAYMENTS P
GROUP BY P.INVOICE_ID) p
WHERE P.INVOICE_ID = I.ID
AND p.TOT_PAID = i.TOT_AMT
ORDER BY PAY_TYPE
结果:
ID TOT_AMT TOT_PAID PAY_TYPE
2 200 0 0_NO_PAYMENTS
1 100 60 1_PARTIALLY_PAID
3 300 300 2_FULLY_PAID
答案 2 :(得分:0)
select * from table1 where not exists(select * from table2 where table2.foreignkey = table1.primarykey)
这有用吗?
答案 3 :(得分:0)
根据您的问题,我看不出任何方法可以判断发票是否已全额付款,但以下内容会为您提供一张没有付款的发票清单,后面会列出已付款的发票清单。
select *
from
invoices
where
not exists (
select 1
from payments
where invoices.id = payments.invoiceid
)
union
select *
from
invoices
where
exists (
select 1
from payments
where invoices.id = payments.invoiceid
)
答案 4 :(得分:0)
SELECT i.id FROM invoices i
LEFT JOIN PAYMENTS p ON i.id = p.invoice_id
GROUP BY i.id, i.amount
ORDER BY SUM(p.amount) / i.amount
如果这样可行,我会感到惊讶。
答案 5 :(得分:0)
select sub.*, paid/tot_amt as ordering_column
from (
select
i.id,
i.customerid,
i.timestamp,
i.tot_amt,
(select sum(ifnull(p.amount,0)) from payments p where p.invoiceid = i.id ) as paid
from invoices i
) sub
order by ordering_column
这将为您提供按照您想要的方式分类的发票,以及每张发票的付款金额总和