Foxpro
如果沒有日期參數或條目的行,則從表中獲取日期參數之前的最後一個日期的行
我有一張桌子,裡面有貨幣的匯率。還有一個
Date
列,保存貨幣匯率的獲取日期。對於某些日期,有一行,但沒有貨幣匯率,對於某些日期,該表中沒有行。
要獲取特定日期的貨幣匯率,我需要將日期作為參數傳遞。
SELECT documentHead.r_art AS documentHeadDocClass, foreignCurrency.usd_brief AS foreignCurrencyUSDAsk, foreignCurrency.usd_geld AS foreignCurrencyUSDBid, foreignCurrency.chf_brief AS foreignCurrencyCHFAsk, foreignCurrency.chf_geld AS foreignCurrencyCHFBid, foreignCurrency.gbp_brief AS foreignCurrencyGBPAsk, foreignCurrency.gbp_geld AS foreignCurrencyGBPBid, foreignCurrency.jpy_brief AS foreignCurrencyJPYAsk, foreignCurrency.jpy_geld AS foreignCurrencyJPYBid, documentListPeriods.id AS documentPeriodsID, documentListPeriods.von AS documentPeriodsFrom, documentListPeriods.bis AS documentPeriodsTo, documentListPeriods.tage AS documentPeriodsDays, documentListPeriods.rate AS documentPeriodsRate, documentListPeriods.wert AS documentPeriodsWorth FROM ( SELECT documentPeriods.id AS documentPeriodsID, documentPeriods.von AS documentPeriodsFrom, documentPeriods.bis AS documentPeriodsTo, documentPeriods.tage AS documentPeriodsDays, documentPeriods.rate AS documentPeriodsRate, documentPeriods.wert AS documentPeriodsWorth FROM comperiode AS documentPeriods WHERE documentPeriods.id = 1 ) AS documentListPeriods INNER JOIN tckopf AS documentHead ON documentHead.id = 1 LEFT OUTER JOIN devisen AS foreignCurrency ON foreignCurrency.datum = documentHead.datum
如何獲取貨幣匯率表行,其中貨幣匯率存在並且日期等於傳遞的日期參數或傳遞的日期參數之前的最後一個日期?
問題是:
LEFT OUTER JOIN devisen AS foreignCurrency ON foreignCurrency.datum = documentHead.datum
如果
foreignCurrency.datum
不存在的行或貨幣匯率為NULL
。如果我使用LEFT OUTER JOIN devisen AS foreignCurrency ON foreignCurrency.datum <= documentHead.datum
我得到的都小於
foreignCurrency.datum
,但我只需要最新的行。在以下範例中,缺少日期行或所有列均為
NULL
. 的行:如果
documentHead.datum
是2009-08-09
並且該日期沒有行,我需要最新的行。在這種情況下,為2009-08-07
.我嘗試使用
TOP 1
並重寫LEFT OUTER JOIN
以下內容:SELECT documentHead.r_art AS documentHeadDocClass, foreignCurrency.usd_brief AS foreignCurrencyUSDAsk, foreignCurrency.usd_geld AS foreignCurrencyUSDBid, foreignCurrency.chf_brief AS foreignCurrencyCHFAsk, foreignCurrency.chf_geld AS foreignCurrencyCHFBid, foreignCurrency.gbp_brief AS foreignCurrencyGBPAsk, foreignCurrency.gbp_geld AS foreignCurrencyGBPBid, foreignCurrency.jpy_brief AS foreignCurrencyJPYAsk, foreignCurrency.jpy_geld AS foreignCurrencyJPYBid, documentListPeriods.id AS documentPeriodsID, documentListPeriods.von AS documentPeriodsFrom, documentListPeriods.bis AS documentPeriodsTo, documentListPeriods.tage AS documentPeriodsDays, documentListPeriods.rate AS documentPeriodsRate, documentListPeriods.wert AS documentPeriodsWorth FROM ( SELECT documentPeriods.id AS documentPeriodsID, documentPeriods.von AS documentPeriodsFrom, documentPeriods.bis AS documentPeriodsTo, documentPeriods.tage AS documentPeriodsDays, documentPeriods.rate AS documentPeriodsRate, documentPeriods.wert AS documentPeriodsWorth FROM comperiode AS documentPeriods WHERE documentPeriods.id = $P{document_id} ) AS documentListPeriods INNER JOIN tckopf AS documentHead ON documentHead.id = $P{document_id} LEFT OUTER JOIN ( SELECT TOP 1 foreignCurrency.usd_brief AS foreignCurrencyUSDAsk, foreignCurrency.usd_geld AS foreignCurrencyUSDBid, foreignCurrency.chf_brief AS foreignCurrencyCHFAsk, foreignCurrency.chf_geld AS foreignCurrencyCHFBid, foreignCurrency.gbp_brief AS foreignCurrencyGBPAsk, foreignCurrency.gbp_geld AS foreignCurrencyGBPBid, foreignCurrency.jpy_brief AS foreignCurrencyJPYAsk, foreignCurrency.jpy_geld AS foreignCurrencyJPYBid FROM devisen AS foreignCurrency WHERE foreignCurrency.datum <= documentHead.$P!{exchangeRateTiming} AND foreignCurrency.datum IS NOT NULL AND foreignCurrency.usd_brief IS NOT NULL AND foreignCurrency.usd_geld IS NOT NULL AND foreignCurrency.chf_brief IS NOT NULL AND foreignCurrency.chf_geld IS NOT NULL AND foreignCurrency.gbp_brief IS NOT NULL AND foreignCurrency.gbp_geld IS NOT NULL AND foreignCurrency.jpy_brief IS NOT NULL AND foreignCurrency.jpy_geld IS NOT NULL ORDER BY foreignCurrency.datum DESC ) AS foreignCurrency
但後來我在 iReport 中得到一個空指針異常:
Error filling print... Error executing SQL statement for : boss_charterfaktura_document_list_interval_positions Setting up the file resolver... net.sf.jasperreports.engine.JRException: Error executing SQL statement for : boss_charterfaktura_document_list_interval_positions at net.sf.jasperreports.engine.query.JRJdbcQueryExecuter.createDatasource(JRJdbcQueryExecuter.java:246) at net.sf.jasperreports.engine.fill.JRFillDataset.createQueryDatasource(JRFillDataset.java:1086) at net.sf.jasperreports.engine.fill.JRFillDataset.initDatasource(JRFillDataset.java:667) at net.sf.jasperreports.engine.fill.JRBaseFiller.setParameters(JRBaseFiller.java:1253) at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:877) at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:822) at net.sf.jasperreports.engine.fill.JRFiller.fill(JRFiller.java:61) at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:446) at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:276) at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:745) at com.jaspersoft.ireport.designer.compiler.IReportCompiler.run(IReportCompiler.java:891) at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:572) at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:997) Caused by: java.sql.SQLException: java.lang.NullPointerException at com.hxtt.sql.dl.a(Unknown Source) at com.hxtt.sql.c3.a(Unknown Source) at com.hxtt.sql.aj.else(Unknown Source) at com.hxtt.sql.aj.cm(Unknown Source) at com.hxtt.sql.aj.s(Unknown Source) at com.hxtt.sql.dl.a(Unknown Source) at com.hxtt.sql.dl.a(Unknown Source) at com.hxtt.sql.el.a(Unknown Source) at com.hxtt.sql.dl.a(Unknown Source) at com.hxtt.sql.br.a(Unknown Source) at com.hxtt.sql.ai.a(Unknown Source) at com.hxtt.sql.dn.executeQuery(Unknown Source) at net.sf.jasperreports.engine.query.JRJdbcQueryExecuter.createDatasource(JRJdbcQueryExecuter.java:239) at net.sf.jasperreports.engine.fill.JRFillDataset.createQueryDatasource(JRFillDataset.java:1086) at net.sf.jasperreports.engine.fill.JRFillDataset.initDatasource(JRFillDataset.java:667) at net.sf.jasperreports.engine.fill.JRBaseFiller.setParameters(JRBaseFiller.java:1253) at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:877) at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:822) at net.sf.jasperreports.engine.fill.JRFiller.fill(JRFiller.java:61) at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:446) at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:276) at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:745) at com.jaspersoft.ireport.designer.compiler.IReportCompiler.run(IReportCompiler.java:891) at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:572) at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:997) at com.hxtt.global.SQLState.SQLException(Unknown Source) at com.hxtt.sql.br.a(Unknown Source) at com.hxtt.sql.ai.a(Unknown Source) at com.hxtt.sql.dn.executeQuery(Unknown Source) at net.sf.jasperreports.engine.query.JRJdbcQueryExecuter.createDatasource(JRJdbcQueryExecuter.java:239) ... 12 more Print not filled. Try to use an EmptyDataSource...
如何在 SQL 中實現這一點?
這種類型的查詢可以使用派生表或相關子查詢或在具有視窗函式的現代 DBMS 中完成。一些 DBMS 對標準 SQL 語法有特殊的專有擴展,如 SQL-Server
OUTER APPLY
和 PostgreSQL 的DISTINCT ON
,也可以用來解決這類問題。由於 FoxPro 沒有這些,您可以使用派生表方法或我稱之為*“窮人
OUTER APPLY
”*的方法:SELECT dh.r_art AS documentHeadDocClass, fc.usd_brief AS foreignCurrencyUSDAsk, fc.usd_geld AS foreignCurrencyUSDBid, fc.chf_brief AS foreignCurrencyCHFAsk, fc.chf_geld AS foreignCurrencyCHFBid, fc.gbp_brief AS foreignCurrencyGBPAsk, fc.gbp_geld AS foreignCurrencyGBPBid, fc.jpy_brief AS foreignCurrencyJPYAsk, fc.jpy_geld AS foreignCurrencyJPYBid, dp.id AS documentPeriodsID, dp.von AS documentPeriodsFrom, dp.bis AS documentPeriodsTo, dp.tage AS documentPeriodsDays, dp.rate AS documentPeriodsRate, dp.wert AS documentPeriodsWorth FROM comperiode AS dp -- documentPeriods INNER JOIN tckopf AS dh -- documentHead ON dh.id = dp.id LEFT OUTER JOIN devisen AS fc -- foreignCurrency ON fc.datum = ( SELECT TOP (1) fci.datum FROM devisen AS fci WHERE fci.datum <= dh.datum ORDER BY fci.datum DESC ) WHERE dh.id = $P{document_id} AND dp.id = $P{document_id} ;
我認為您忘記
ON
在末尾添加子句:SELECT documentHead.r_art AS documentHeadDocClass, foreignCurrency.usd_brief AS foreignCurrencyUSDAsk, foreignCurrency.usd_geld AS foreignCurrencyUSDBid, foreignCurrency.chf_brief AS foreignCurrencyCHFAsk, foreignCurrency.chf_geld AS foreignCurrencyCHFBid, foreignCurrency.gbp_brief AS foreignCurrencyGBPAsk, foreignCurrency.gbp_geld AS foreignCurrencyGBPBid, foreignCurrency.jpy_brief AS foreignCurrencyJPYAsk, foreignCurrency.jpy_geld AS foreignCurrencyJPYBid, documentListPeriods.id AS documentPeriodsID, documentListPeriods.von AS documentPeriodsFrom, documentListPeriods.bis AS documentPeriodsTo, documentListPeriods.tage AS documentPeriodsDays, documentListPeriods.rate AS documentPeriodsRate, documentListPeriods.wert AS documentPeriodsWorth FROM ( SELECT documentPeriods.id AS documentPeriodsID, documentPeriods.von AS documentPeriodsFrom, documentPeriods.bis AS documentPeriodsTo, documentPeriods.tage AS documentPeriodsDays, documentPeriods.rate AS documentPeriodsRate, documentPeriods.wert AS documentPeriodsWorth FROM comperiode AS documentPeriods WHERE documentPeriods.id = $P{document_id} ) AS documentListPeriods INNER JOIN tckopf AS documentHead ON documentHead.id = $P{document_id} LEFT OUTER JOIN ( SELECT TOP 1 fc.usd_brief AS foreignCurrencyUSDAsk, fc.usd_geld AS foreignCurrencyUSDBid, fc.chf_brief AS foreignCurrencyCHFAsk, fc.chf_geld AS foreignCurrencyCHFBid, fc.gbp_brief AS foreignCurrencyGBPAsk, fc.gbp_geld AS foreignCurrencyGBPBid, fc.jpy_brief AS foreignCurrencyJPYAsk, fc.jpy_geld AS foreignCurrencyJPYBidб fc.datum FROM devisen AS fс WHERE fc.datum <= $P!{exchangeRateTiming} AND fc.datum IS NOT NULL AND fc.usd_brief IS NOT NULL AND fc.usd_geld IS NOT NULL AND fc.chf_brief IS NOT NULL AND fc.chf_geld IS NOT NULL AND fc.gbp_brief IS NOT NULL AND fc.gbp_geld IS NOT NULL AND fc.jpy_brief IS NOT NULL AND fc.jpy_geld IS NOT NULL ORDER BY fc.datum DESC ) AS foreignCurrency ON foreignCurrency.datum = documentHead.datum
順便說一句,我不喜歡在子查詢內部和外部重複使用別名。因此我引入了一個
fc
別名