结合使用UNION ALL和子查询和变量的MySQL错误

paul724

我有一个表currency_lkp和一个表associate_data,associate_data有以下列-货币,发票总额和状态(未付款,已付款或等待中),我可以成功地将表与该查询的上半部分链接(请参阅MySQL小提琴),并提供总计每种货币。

我还可以为转换为USD的每种状态提供正确的总计(请参见查询的下半部分,该行产生一行

当我在两半之间使用UNION ALL时,会产生结果,但中间三列的数字非常奇怪,但在第四列和该列的最后一行中却是正确的结果。

我认为查询还可以,但如果可以在子查询中使用变量,则可以更整洁。任何关于出问题或如何改善优雅的想法将不胜感激-谢谢

要创建示例数据库:(在此下方的MySQL查询)

    CREATE TABLE IF NOT EXISTS `currency_lkp` (
  `currency_id` int(11) NOT NULL AUTO_INCREMENT,
  `currency` varchar(10) NOT NULL,
  `currency_label` varchar(100) NOT NULL,
  `currency_description` varchar(100) NOT NULL,
  `exchange_rate_USD` float NOT NULL,
  PRIMARY KEY (`currency_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;

INSERT INTO `currency_lkp` (`currency_id`, `currency`, 
`currency_label`, `currency_description`, `exchange_rate_USD`)
VALUES
(1, 'GBP', '£', 'Great British Pound (Sterling)', 0.75),
(2, 'Euro', '€', 'Euro currency for the Euro Zone', 0.85),
(3, 'USD', '$', 'United States Dollars', 1),
(4, 'CLP', '$', 'Chilean Pesos', 639.85),
(5, 'INR', '&#8377', 'Indian Rupees', 64.8);

CREATE TABLE IF NOT EXISTS `associate_data` (`associate_data_id`
int(11) NOT NULL AUTO_INCREMENT,
`currency` varchar(10) NOT NULL, 
`status` varchar(20) NOT NULL, 
`invoice_total` float,
 PRIMARY KEY (`associate_data_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;

INSERT INTO `associate_data` (`associate_data_id`, `currency`, 
`status`, `invoice_total`)
 VALUES
(1, 'GBP', 'Paid', 200),
(2, 'GBP', 'Unpaid', 300),
(3, 'Euro', 'Paid', 1000),
(4, 'Euro', 'Unpaid', 2000),
(5, 'USD', 'Paid', 1200),
(6, 'USD', 'Unpaid', 1400),
(7, 'GBP', 'WaitingInvoice', 400),
(8, 'Euro', 'WaitingInvoice', 1300),
(9, 'USD', 'WaitingInvoice', 2300),
(10, 'CLP', 'Paid', 100200),
(11, 'CLP', 'Unpaid', 110400),
(12, 'CLP', 'WaitingInvoice', 11200);

MySQL Query in full:
`
(
SELECT cl.currency,
(SELECT SUM(invoice_total) FROM associate_data ad2
WHERE ad2.currency = cl.currency  AND ad2.status = 'Paid') AS Paid,
(SELECT SUM(invoice_total) FROM associate_data ad3
WHERE ad3.currency = cl.currency  AND ad3.status = 'Unpaid') AS Unpaid,
(SELECT SUM(invoice_total) FROM associate_data ad4
WHERE ad4.currency = cl.currency  AND ad4.status = 'WaitingInvoice') AS WaitingInvoice,
(SELECT IFNULL(Unpaid,0) + IFNULL(WaitingInvoice, 0)) AS TotalToPay
FROM currency_lkp cl
)

UNION ALL

(
SELECT 'Total in USD',

FORMAT(
SUM(IFNULL(
(SELECT SUM(invoice_total) FROM associate_data ad5
WHERE ad5.currency = clu.currency AND (ad5.status = 'Paid'))
,0.1)/clu.exchange_rate_USD)
,0) AS TotalUSDPaid,

FORMAT(
SUM(IFNULL(
(SELECT SUM(invoice_total) FROM associate_data ad6
WHERE ad6.currency = clu.currency AND (ad6.status = 'Unpaid'))
,0.1)/clu.exchange_rate_USD)
,0) AS TotalUSDUnpaid,

FORMAT(
SUM(IFNULL(
(SELECT SUM(invoice_total) FROM associate_data ad6
WHERE ad6.currency = clu.currency AND (ad6.status = 'WaitingInvoice'))
,0.1)/clu.exchange_rate_USD)
,0) AS TotalUSDWaitingInvoice,

FORMAT(
SUM(IFNULL(
(SELECT SUM(invoice_total) FROM associate_data ad6
WHERE ad6.currency = clu.currency AND (ad6.status = 'WaitingInvoice' OR ad6.status = 'Unpaid'))
,0.1)/clu.exchange_rate_USD)
,0) AS TotalUSDToPay
FROM currency_lkp clu
)`
Used_By_Already

您可以使用“条件聚合”(聚合函数中的一个条件表达式)从根本上简化查询(并提高效率),如下所示:

select
      cu.currency
    , sum(case when ad.status = 'Paid' then invoice_total end) as Paid
    , sum(case when ad.status = 'Unpaid' then invoice_total end) as Unpaid
    , sum(case when ad.status = 'WaitingInvoice' then invoice_total end) as WaitingInvoice_USD
    , FORMAT(sum(case when ad.status = 'Paid' then invoice_total/cu.exchange_rate_USD end),0) as Paid_USD
    , FORMAT(sum(case when ad.status = 'Unpaid' then invoice_total/cu.exchange_rate_USD end),0) as Unpaid_USD
    , FORMAT(sum(case when ad.status = 'WaitingInvoice' then invoice_total/cu.exchange_rate_USD end),0) as WaitingInvoice_USD  
FROM associate_data ad
inner join currency_lkp cu ON ad.currency = cu.currency
group by
      cu.currency
union all
select
      'Total'
    , sum(case when ad.status = 'Paid' then invoice_total end) as Paid
    , sum(case when ad.status = 'Unpaid' then invoice_total end) as Unpaid
    , sum(case when ad.status = 'WaitingInvoice' then invoice_total end) as WaitingInvoice_USD
    , FORMAT(sum(case when ad.status = 'Paid' then invoice_total/cu.exchange_rate_USD end),0) as Paid_USD
    , FORMAT(sum(case when ad.status = 'Unpaid' then invoice_total/cu.exchange_rate_USD end),0) as Unpaid_USD
    , FORMAT(sum(case when ad.status = 'WaitingInvoice' then invoice_total/cu.exchange_rate_USD end),0) as WaitingInvoice_USD  
FROM associate_data ad
inner join currency_lkp cu ON ad.currency = cu.currency
;

该查询产生以下结果:

| currency |   Paid | Unpaid | WaitingInvoice_USD | Paid_USD | Unpaid_USD | WaitingInvoice_USD |
|----------|--------|--------|--------------------|----------|------------|--------------------|
|      CLP | 100200 | 110400 |              11200 |      157 |        173 |                 18 |
|     Euro |   1000 |   2000 |               1300 |    1,176 |      2,353 |              1,529 |
|      GBP |    200 |    300 |                400 |      267 |        400 |                533 |
|      USD |   1200 |   1400 |               2300 |    1,200 |      1,400 |              2,300 |
|    Total | 102600 | 114100 |              15200 |    2,800 |      4,325 |              4,380 |

观看此演示:http : //sqlfiddle.com/#!9/ b4b5bb/ 36

在先前查询的某些列中出现了gobbledygook的原因是试图在同一列中合并数字和格式化的(文本)数据。除掉format( ,0)

参见:http : //sqlfiddle.com/#!9/b4b5bb/37

(
SELECT cl.currency,
(SELECT SUM(invoice_total) FROM associate_data ad2
WHERE ad2.currency = cl.currency  AND ad2.status = 'Paid') AS Paid,
(SELECT SUM(invoice_total) FROM associate_data ad3
WHERE ad3.currency = cl.currency  AND ad3.status = 'Unpaid') AS Unpaid,
(SELECT SUM(invoice_total) FROM associate_data ad4
WHERE ad4.currency = cl.currency  AND ad4.status = 'WaitingInvoice') AS WaitingInvoice,
(SELECT IFNULL(Unpaid,0) + IFNULL(WaitingInvoice, 0)) AS TotalToPay
FROM currency_lkp cl
)
UNION ALL
(
SELECT 'Total in USD',


SUM(IFNULL(
(
  SELECT SUM(invoice_total) FROM associate_data ad5
WHERE ad5.currency = clu.currency AND (ad5.status = 'Paid')
),0.1)/clu.exchange_rate_USD) 
  AS TotalUSDPaid,


SUM(IFNULL(
(SELECT SUM(invoice_total) FROM associate_data ad6
WHERE ad6.currency = clu.currency AND (ad6.status = 'Unpaid'))
,0.1)/clu.exchange_rate_USD)
 AS TotalUSDUnpaid,


SUM(IFNULL(
(SELECT SUM(invoice_total) FROM associate_data ad6
WHERE ad6.currency = clu.currency AND (ad6.status = 'WaitingInvoice'))
,0.1)/clu.exchange_rate_USD)
 AS TotalUSDWaitingInvoice,


SUM(IFNULL(
(SELECT SUM(invoice_total) FROM associate_data ad6
WHERE ad6.currency = clu.currency AND (ad6.status = 'WaitingInvoice' OR ad6.status = 'Unpaid'))
,0.1)/clu.exchange_rate_USD)
 AS TotalUSDToPay
FROM currency_lkp clu
)

该查询的结果是:

|     currency |               Paid |           Unpaid |    WaitingInvoice |        TotalToPay |
|--------------|--------------------|------------------|-------------------|-------------------|
|          GBP |                200 |              300 |               400 |               700 |
|         Euro |               1000 |             2000 |              1300 |              3300 |
|          USD |               1200 |             1400 |              2300 |              3700 |
|          CLP |             100200 |           110400 |             11200 |            121600 |
|          INR |             (null) |           (null) |            (null) |                 0 |
| Total in USD | 2799.7379740260294 | 4325.48309943104 | 4380.250701542091 | 8705.732257763328 |

注意:我没有尝试更正任何查询算法,但显然其中之一是错误的

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章