组合多个SQL查询一起
我有多个表项目(课程,费用和付款)组合多个SQL查询一起
为了让我做的会话执行以下操作:
SELECT
sess.file_id, SUM(sess.rate * sess.length) AS total
FROM
sess
WHERE sess.sessionDone = 1
GROUP BY sess.file_id
这将返回量特定学生要
我也有另一个表“费用”
SELECT
file_charges.file_id, SUM(file_charges.price) AS total_charges
FROM
file_charges
GROUP BY file_charges.file_id
最后付款查询:
SELECT
file_payments.file_id, SUM(file_payments.paymentAmount) AS total_payment
FROM
file_payments
GROUP BY file_payments.file_id
我可以结合这些3的方式有:
Total = Payments - (Session + Charges)
注意,也可能是负面,所以我可以有一个存在的会话,费用的file_id但不付款,我能有没有会议或收费的支付...
的一个问题是,是否这些查询的一个可以“驱动程序”,在情况下,我们没有通过一个或多个返回给定file_id
行的查询。 (例如,有可能是从sess
行,但没有从file_payments
如果我们想一定要包括出现在任何一个查询的每一个可能的file_id
,我们可以得到所有可能的file_id
列表,像这样的查询:
SELECT ss.file_id FROM sess ss
UNION
SELECT fc.file_id FROM file_charges fc
UNION
SELECT fp.file_id FROM file_payments fp
(注:UNION运算符将删除任何重复)
能获得指定的结果集,我们可以使用查询,伴随着“左加入”其他三个原始查询的查询的轮廓。将是:
SELECT a.file_id, p.total_payment - (s.total + c.total_charges)
FROM a
LEFT JOIN s ON s.file_id = a.file_id
LEFT JOIN c ON c.file_id = a.file_id
LEFT JOIN p ON p.file_id = a.file_id
ORDER BY a.file_id
在该声明中,a
是查询的一个替代品,它获取所有file_id
值的集合(如上所示)。 s
,c
和p
分别是您的三个原始查询的站点,分别位于sess,file_charges和file_payments。
如果有任何file_id
值在任何查询中“缺失”,我们将需要用零代替缺失值。我们可以使用IFNULL函数为我们处理。
该查询应返回结果集指定:
SELECT a.file_id
, IFNULL(p.total_payment,0) - (IFNULL(s.total,0) + IFNULL(c.total_charges,0)) AS t
FROM (-- all possible values of file_id
SELECT ss.file_id FROM sess ss
UNION
SELECT fc.file_id FROM file_charges fc
UNION
SELECT fp.file_id FROM file_payments fp
) a
LEFT
JOIN (-- the amount that a specific student should pay
SELECT sess.file_id, SUM(sess.rate * sess.length) AS total
FROM sess
WHERE sess.sessionDone = 1
GROUP BY sess.file_id
) s
ON s.file_id = a.file_id
LEFT
JOIN (-- charges
SELECT file_charges.file_id, SUM(file_charges.price) AS total_charges
FROM file_charges
GROUP BY file_charges.file_id
) c
ON c.file_id = a.file_id
LEFT
JOIN (-- payments
SELECT file_payments.file_id, SUM(file_payments.paymentAmount) AS total_payment
FROM file_payments
GROUP BY file_payments.file_id
) p
ON p.file_id = a.file_id
ORDER BY a.file_id
(该解释这种查询不会是漂亮,有四个派生表。在大集合上,表现可能是可怕的。但返回的结果集应该符合规范。)
要小心将所有三个表连接在一起的查询......如果存在(例如)两个(或多个)行,则可能会给出不正确的结果file_payment
表。
还有其他方法可以获得等效的结果集,但上面的查询回答了这个问题:“我怎样才能将这些查询的结果合并为一个总数”。
使用相关子查询
这里的另一种方法,在SELECT列表中使用相关子查询...
SELECT a.file_id
, IFNULL((SELECT SUM(file_payments.paymentAmount) FROM file_payments
WHERE file_payments.file_id = a.file_id)
,0)
- (IFNULL((SELECT SUM(sess.rate * sess.length) FROM sess
WHERE sess.file_id = a.file_id)
,0)
+ IFNULL((SELECT SUM(file_charges.price) FROM file_charges
WHERE file_charges.file_id = a.file_id)
,0)
) AS tot
FROM (-- all file_id values
SELECT ss.file_id FROM sess ss
UNION
SELECT fc.file_id FROM file_charges fc
UNION
SELECT fp.file_id FROM file_payments fp
) a
ORDER BY a.file_id
试试这个
SELECT sess.file_id, SUM(file_payments.paymentAmount) - (SUM(sess.rate * sess.length)+SUM(file_charges.price)) as total_payment FROM sess , file_charges , file_payments
WHERE sess.sessionDone = 1
GROUP BY total_payment
编辑。这需要解决
SELECT a.file_id
, IFNULL(p.total_payment,0) - (IFNULL(s.total,0) + IFNULL(c.total_charges,0)) AS tot
FROM (
SELECT ss.file_id FROM sess ss
UNION
SELECT fc.file_id FROM file_charges fc
UNION
SELECT fp.file_id FROM file_payments fp
) a
LEFT JOIN (
SELECT sess.file_id, SUM(sess.rate * sess.length) AS total
FROM sess
WHERE sess.sessionDone = 1
GROUP BY sess.file_id
) s
ON s.file_id = a.file_id
LEFT JOIN (
SELECT file_charges.file_id, SUM(file_charges.price) AS total_charges
FROM file_charges
GROUP BY file_charges.file_id
) c
ON c.file_id = a.file_id
LEFT JOIN (
SELECT file_payments.file_id, SUM(file_payments.paymentAmount) AS total_payment
FROM file_payments
GROUP BY file_payments.file_id
) p
ON p.file_id = a.file_id
ORDER BY a.file_id
你无法按total_payment,因为有很多学生,我需要知道学生的身份证号码是否为负值(file_id是特定学生的档案) – commandos
看我的编辑答案 –
谢谢,但我想要的是所有学生:)不是特定的e ...已经解决了特定学生的问题。 – commandos