過去問解説見直し依頼(検討案)(R6秋午後問6)
広告
GinSanaさん
★AP プラチナマイスター
(No.1)
管理人さんへ
平素よりお世話になっております。
https://www.ap-siken.com/kakomon/06_aki/pm06.html
応用情報技術者過去問題 令和6年秋期 午後問6
設問2 空欄f
の解説の
少々ややこしい話なので、一旦結論として書かせていただきました。
・・・・・・・
以降は補足です。
通常のよくある再帰でないUNION(DISTINCT)/UNION ALLであれば、パフォーマンスという側面で説明して問題ないようには思います。
そして、SQL標準でもUNION(DISTINCT)を使用して説明している部分がある(※)ので、(SQL標準のように、「概念としての実装指針」であり、実装上でない)理屈の上では問題ないので、IPAも許容する解答となるのだと思われます。
※:sql server - Why does a Recursive CTE in Transact-SQL require a UNION ALL and not a UNION? - Stack Overflow
「There are quite a few places in the SQL Standards where code is used demonstrating UNION such as below」の後の図表のように
実際のDBMSでは、再帰で積んでいくスタック・スプールは、その都度読んだ行を削除する都合上、UNION DISTINCT後の行が、「削除された行と重複しているかどうかを知ることはできない」という根本的な問題があります。その問題に対応するために、各RDBMS側の実装で無理矢理迂回しているのが実情です(技術的な制限)。
これの問題は、終了するか無限ループするかの違いを生む可能性が出てくることでもあります。
一般的な考え方では、UNIONでは、バックグラウンドでソート操作が必要になり、以前の反復処理の結果が修正される可能性があります。
プログラムは、コールスタック内の以前の呼び出しの状態を変更してはならず、入力パラメータと後続の反復処理の結果 (手続き型設定) を使用して、その呼び出しと対話する必要があります。
スタックに積んで、終了条件が来るまではUNIONの重複排除対象が出来上がらず、すべてのスタックから取り出した後でsort+uniqを行う、という流れになります。
たとえばSQLiteであれば、重複をチェックするために、UNIONの場合以前に生成されたすべてのコンテンツを保持する必要があり、メモリがパンクするリスクがあるという意味では、「パフォーマンス面で優れるUNION ALLの方がより適切な解答」という落とし込みでもよいと考えられます。
UNION ALLはそれに必要なリソースを準備しなくともよいという点で、「パフォーマンス面で優れる」という説明をしても問題はないと思います。
しかし、実際のDBMSが採用しているかはわからないので、一般論として再帰のDISTINCTの問題を、パフォーマンスで説明をするべきかというと、違うように思います。
レコードの構成はどうあれ、原理的に無限ループに至りかねない処理をさせるべきではない、という観点から、UNIONは再帰においてshould notとして推奨しない、ということを示しておくべきではないかと思います。
平素よりお世話になっております。
https://www.ap-siken.com/kakomon/06_aki/pm06.html
応用情報技術者過去問題 令和6年秋期 午後問6
設問2 空欄f
の解説の
したがって、空欄eには「WITH RECURSIVE」が、空欄fには「UNION ALL」が当てはまります。なお、各SQL文の結果には重複するレコードが含まれていないため、UNIONを使用しても同じ結果になります。ただし、パフォーマンス面で優れるUNION ALLの方がより適切な解答と言えます。
について、一旦こう直すとよいのではないか、という案を書きます。「なお、各SQL文の結果には重複するレコードが含まれていないため、UNIONを使用しても同じ結果になります。」という結論への至り方が、一般的なUNIONと再帰でのUNIONについては結構異なります。ここを意識させる解説にしたほうが、よりよい理解につながると思われます。少々ややこしい話なので、一旦結論として書かせていただきました。
したがって、空欄eには「WITH RECURSIVE」が、空欄fには「UNION ALL」が当てはまります。なお、各SQL文の結果には重複するレコードが含まれていないため、UNIONを使用した場合においても、概念上は重複削除と再帰処理の順序で問題は発生しないため、許容されると考えられます。ただし、実際のSQLでは、UNIONの場合、重複削除と再帰処理の順序の担保について各RDBMSにより独自の処理が行われ、場合によっては無限ループを引き起こす可能性があるため、推奨されません。
・・・・・・・
以降は補足です。
通常のよくある再帰でないUNION(DISTINCT)/UNION ALLであれば、パフォーマンスという側面で説明して問題ないようには思います。
そして、SQL標準でもUNION(DISTINCT)を使用して説明している部分がある(※)ので、(SQL標準のように、「概念としての実装指針」であり、実装上でない)理屈の上では問題ないので、IPAも許容する解答となるのだと思われます。
※:sql server - Why does a Recursive CTE in Transact-SQL require a UNION ALL and not a UNION? - Stack Overflow
「There are quite a few places in the SQL Standards where code is used demonstrating UNION such as below」の後の図表のように
実際のDBMSでは、再帰で積んでいくスタック・スプールは、その都度読んだ行を削除する都合上、UNION DISTINCT後の行が、「削除された行と重複しているかどうかを知ることはできない」という根本的な問題があります。その問題に対応するために、各RDBMS側の実装で無理矢理迂回しているのが実情です(技術的な制限)。
これの問題は、終了するか無限ループするかの違いを生む可能性が出てくることでもあります。
一般的な考え方では、UNIONでは、バックグラウンドでソート操作が必要になり、以前の反復処理の結果が修正される可能性があります。
プログラムは、コールスタック内の以前の呼び出しの状態を変更してはならず、入力パラメータと後続の反復処理の結果 (手続き型設定) を使用して、その呼び出しと対話する必要があります。
スタックに積んで、終了条件が来るまではUNIONの重複排除対象が出来上がらず、すべてのスタックから取り出した後でsort+uniqを行う、という流れになります。
たとえばSQLiteであれば、重複をチェックするために、UNIONの場合以前に生成されたすべてのコンテンツを保持する必要があり、メモリがパンクするリスクがあるという意味では、「パフォーマンス面で優れるUNION ALLの方がより適切な解答」という落とし込みでもよいと考えられます。
UNION ALLはそれに必要なリソースを準備しなくともよいという点で、「パフォーマンス面で優れる」という説明をしても問題はないと思います。
しかし、実際のDBMSが採用しているかはわからないので、一般論として再帰のDISTINCTの問題を、パフォーマンスで説明をするべきかというと、違うように思います。
レコードの構成はどうあれ、原理的に無限ループに至りかねない処理をさせるべきではない、という観点から、UNIONは再帰においてshould notとして推奨しない、ということを示しておくべきではないかと思います。
2025.04.07 19:54
管理人
(No.2)
ご提案ありがとうございます。
Stack Overflowの記事も拝見しましたが、非常に専門的な内容であり、不勉強ながらまだ完全な理解に至っておりません。解説の案をいただいたので、応用情報技術者の受験者に必要な範囲で正確な説明となるように解説の改善を検討させていただきます。
Stack Overflowの記事も拝見しましたが、非常に専門的な内容であり、不勉強ながらまだ完全な理解に至っておりません。解説の案をいただいたので、応用情報技術者の受験者に必要な範囲で正確な説明となるように解説の改善を検討させていただきます。
2025.04.09 22:59
DTさん
(No.3)
そこまで細かい説明が必要なのでしょうか。
2025.04.16 03:50
GinSanaさん
★AP プラチナマイスター
(No.4)
>DTさん(No.3)
まあ、応用情報に閉じた話で、現実で再帰でのUNION DISTINCTを使わないなら、いいとは思ってます。実際に使って失敗した際に、応用情報ドットコムの解説ではどうの、とか言われたときに、なんか嫌な感じがするくらいですね。
受験者の実生活に跳ね返ってくるべき内容の試験で、技術者以外も受けてるんだから仔細な話だからどうでもよい、とその辺をごまかしてもあんまりいいことはないかな、と思っているところです。
2025.04.16 11:53
DTさん
(No.5)
受験者は様々な背景があるので、全員がここまで詳しく説明を求めていないのではないでしょうか。
私は、余計分からなくなるのでここまで詳細は知りたくないです。
「より詳細の説明が必要であれば、リンクやボタンを押下したら詳細を表示する」ようなことが技術的に出来れば良いですね。
私は、余計分からなくなるのでここまで詳細は知りたくないです。
「より詳細の説明が必要であれば、リンクやボタンを押下したら詳細を表示する」ようなことが技術的に出来れば良いですね。
2025.04.16 12:45
GinSanaさん
★AP プラチナマイスター
(No.6)
>「より詳細の説明が必要であれば、リンクやボタンを押下したら詳細を表示する」ようなことが技術的に出来れば良いですね。
よい案だと思います。
よく、私が読む左門至峰の過去問の解説本だと、
ここからは直接関係ありませんので興味のない方は飛ばしてください、とかあったりするので、最初は閉じているダイアログにしておいて、興味のある方は展開、とかできるといいなと思います。
2025.04.16 13:32
管理人
(No.7)
さらなるご考察を賜り、感謝申し上げます。
設問2のfに関して、解答例ではUNION ALLの単独であり、『なぜUNIONではなくUNION ALLなのか』という点について、今後の受験者が疑問を抱く可能性は高いと考えられます。そのような中、GinSanaさんよりご提示いただいた論拠は、UNION ALLが採用されている理由を理論的に裏付けるものであり、解答例の納得感を深めるものとして非常に有意義であると感じました。
DTさんのご意見にあるように、解説の中に長々と補足を入れることはできませんので、最初にGinSanaさんに提供いただいた解説例をもとに以下のような注記を加えることにしてみました。
設問2のfに関して、解答例ではUNION ALLの単独であり、『なぜUNIONではなくUNION ALLなのか』という点について、今後の受験者が疑問を抱く可能性は高いと考えられます。そのような中、GinSanaさんよりご提示いただいた論拠は、UNION ALLが採用されている理由を理論的に裏付けるものであり、解答例の納得感を深めるものとして非常に有意義であると感じました。
DTさんのご意見にあるように、解説の中に長々と補足を入れることはできませんので、最初にGinSanaさんに提供いただいた解説例をもとに以下のような注記を加えることにしてみました。
なお、各SQL文の結果には重複するレコードが含まれていないため、UNIONを使用しても同じ結果になります。ただし、パフォーマンス面や実務上の観点からは、UNION ALLの方がより適切な解答と言えます※。
…
※試験問題および標準SQLの仕様上は、UNION (DISTINCT)でも問題はありません。ただし、実際のSQL実行においては、重複行の削除と再帰処理の実行順序はRDBMSの実装に依存しており、場合によっては無限ループを引き起こす可能性があるため推奨されません。実務上はUNION ALLの使用が推奨されます。
参考URL: https://stackoverflow.com/questions/47998833/why-does-a-recursive-cte-in-transact-sql-require-a-union-all-and-not-a-union
…
※試験問題および標準SQLの仕様上は、UNION (DISTINCT)でも問題はありません。ただし、実際のSQL実行においては、重複行の削除と再帰処理の実行順序はRDBMSの実装に依存しており、場合によっては無限ループを引き起こす可能性があるため推奨されません。実務上はUNION ALLの使用が推奨されます。
参考URL: https://stackoverflow.com/questions/47998833/why-does-a-recursive-cte-in-transact-sql-require-a-union-all-and-not-a-union
2025.04.16 16:42
DTさん
(No.8)
> 管理人(No.7) さん
ご対応ありがとうございます。お手数おかけいたしました。
2025.04.16 20:58
GinSanaさん
★AP プラチナマイスター
(No.9)
管理人さんへ
ご対応ありがとうございます。興味のある人は、その対応である程度読んでもらえると思います。
ご対応ありがとうございます。興味のある人は、その対応である程度読んでもらえると思います。
2025.04.16 20:59
広告
返信投稿用フォーム
スパム防止のためにスレッド作成日から40日経過したスレッドへの投稿はできません。
広告