通貨の為替レートを保持するテーブルがあります。為替レートの取得日を保持する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でnullポインタ例外が発生します。
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-ServerのOUTER APPLY
やPostgreSQLのDISTINCT ON
など、標準のSQL構文に特別な独自の拡張機能があり、この種の問題の解決にも使用できます。
FoxProにはこれらのいずれも含まれていないため、派生テーブルアプローチ、または私が呼ぶものを使用できます"poor man's 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
エイリアスを導入しました