Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

DB2 - problem by creating view with select left join and order by..

Posted on 2013-12-18
5
Medium Priority
?
2,125 Views
Last Modified: 2013-12-19
Hi experts,

I have a problem at creating a view in DB2, although the select itself runs absolutely OK. Here is the commands:

1. runs OK, I become some records:

SELECT t.GUTSCHEINNR, t.K_ART, t.TIERPARK_ID FROM ISIWAS.TPKARTEN t
 left join ISIWAS.TPKARTEN_TIERPARKLISTE l on t.TIERPARK_ID = l.TIERPARK_ID order by GUTSCHEINNR;

2. create with the same select fails:

CREATE VIEW ISIWAS.TPKARTEN_CSV2 AS SELECT t.GUTSCHEINNR, t.K_ART, t.TIERPARK_ID FROM ISIWAS.TPKARTEN t
 left join ISIWAS.TPKARTEN_TIERPARKLISTE l on t.TIERPARK_ID = l.TIERPARK_ID order by GUTSCHEINNR;

Error message (in German, below I give it also in English):

CREATE VIEW ISIWAS.TPKARTEN_CSV2 AS SELECT t.GUTSCHEINNR, t.K_ART, t.TIERPARK_ID FROM ISIWAS.TPKARTEN t left join ISIWAS.TPKARTEN_TIERPARKLISTE l on t.TIERPARK_ID = l.TIERPARK_ID order by GUTSCHEINNR
DB21034E  Der Befehl wurde als SQL-Anweisung verarbeitet, da es sich um keinen
gültigen Befehl des Befehlszeilenprozessors handelte. Während der
SQL-Verarbeitung wurde Folgendes ausgegeben:
SQL20211N  Die Angabe ORDER BY oder FETCH FIRST n ROWS ONLY ist ungültig.  
SQLSTATE=428FJ

SQL20211N  Die Angabe ORDER BY oder FETCH FIRST n ROWS ONLY ist ungültig.

Erläuterung:

ORDER BY und FETCH FIRST n ROWS ONLY ist in folgenden Kontexten nicht
zulässig:
*  äußerer Fullselect einer Sicht
*  äußerer Fullselect in der Anweisung RETURN einer SQL-Tabellenfunktion
*  Definition einer MQT
*  Subselect, der nicht in runde Klammern eingeschlossen ist

Benutzeraktion:

Im Fall von:

Subselect
         Schließen Sie den Subselect, der ORDER BY oder FETCH FIRST n
         ROWS ONLY enthält, in runde Klammern ein.

FETCH FIRST n ROWS ONLY
         Verwenden Sie die Klausel ROW_NUMBER() OVER() zusammen mit
         einem Vergleichselement in der Klausel WHERE. Beispiel:
         SELECT name FROM
           (SELECT
              ROW_NUMBER() OVER() AS m, name
              FROM emp
           ) AS e
         WHERE m < 10


ORDER BY Verwenden Sie in der Abfrage die Klausel ORDER BY unter Angabe
         der Sicht, der MQT oder der SQL-Tabellenfunktion.

sqlcode: -20211

sqlstate: 428FJ


English:
SQL20211N
The specification ORDER BY or FETCH FIRST n ROWS ONLY is invalid.

Explanation
An ORDER BY or FETCH FIRST n ROWS ONLY is not allowed in:
the outer fullselect of a view
the outer fullselect in the RETURN statement of an SQL Table function
a materialized query table definition
a subselect which is not enclosed in parenthesis
User response
In case of:
subselect
Enclose the subselect including the ORDER BY or FETCH FIRST n ROWS ONLY in parenthesis.
FETCH FIRST n ROWS ONLY
Use the ROW_NUMBER() OVER() clause in conjunction with a predicate in the where clause. Example:
SELECT name FROM
  (SELECT
     ROW_NUMBER() OVER() AS m, name
     FROM emp
  ) AS e
WHERE m < 10
ORDER BY
Use ORDER BY in the query using the view, the materialized query table, or the SQL table function instead.
sqlcode: -20211

sqlstate: 428FJ


Can you help me to understand why and how to correct the command to create the view?

Thanx in advance!

Yuriy
0
Comment
Question by:inversojvo
  • 2
  • 2
5 Comments
 
LVL 46

Accepted Solution

by:
Kent Olsen earned 1800 total points
ID: 39726664
Hi nversojvo,

There are several easy ways around this.  One is to sort/select using the OLAP tools (row_num() over ...) etc.

But the easiest is to just wrap the query with an outer query.

  CREATE VIEW myview AS SELECT * FROM mytable ORDER BY 2 FETCH FIRST 1 ROWS ONLY;

Becomes

  CREATE VIEW myview AS SELECT * FROM (SELECT * FROM mytable ORDER YB 2 FETCH FIRST 1 ROWS ONLY) as t0;


Good Luck,
Kent
0
 

Author Comment

by:inversojvo
ID: 39727163
Hi Kent,

you are right, it worked, thanx..

But I wouldn't pretend to understand, why :).

What is the different in those 2 ways of running SQL? Will smth. be checked by saving an SQL as a query, that not checked by running it from the DB2 control center?

Rgds,
Yuriy
0
 
LVL 46

Assisted Solution

by:Kent Olsen
Kent Olsen earned 1800 total points
ID: 39727394
Hi Yuriy,

DB2 has long had a few oddities that seem irritating, but when you understand the parser and rationale, it makes pretty good sense.  Something similar to your issue is that column aliases don't propagate to the filter clause.

  SELECT last || ', ' ||first as full_name FROM mytable WHERE full_name like 'A%';

That's illegal as the alias full_name isn't legal in the filter.  But wrap it in an outer query and all is well.

  SELECT * FROM (SELECT last || ', ' ||first as full_name FROM mytable) as t0
  WHERE full_name like 'A%';

The rationale for not allowing a sort/fetch first as the last item in a view's SELECT statement is performance.  On older versions of DB2 (and perhaps even current ones), DB2 would make two filter passes if the view filtered the results and the query calling the view had its own filter.

  CREATE VIEW v1 AS SELECT * FROM cities WHERE name like 'A%';
  SELECT * FROM v1 WHERE zip LIKE '9%';

In the example above, DB2 filters the results of the view (name like 'A%') and returns the results to the query where a second filtering pass is require to select the rows where zip like '9%'.  It's more efficient to include both clauses in the view or the SELECT statement as both clauses are evaluated in the same pass.

Your situation is similar.  DB2 is simply promoting better SQL, but providing a workaround to do exactly what you want.


Kent
0
 
LVL 27

Assisted Solution

by:tliotta
tliotta earned 200 total points
ID: 39728534
Kent has the correct answer and deserves the credit. The short answer is simply:
Explanation
An ORDER BY or FETCH FIRST n ROWS ONLY is not allowed in:
   the outer fullselect of a view
VIEWs don't have ORDER BY (nor FETCH FIRST) clauses. An ORDER BY is for an INDEX, not a VIEW. Or an ORDER BY is for a run-time SELECT over a VIEW. VIEWs shouldn't have an order imposed on them; it contradicts choices of an order when a user wants a different sequence.

Kent correctly gives a way to make it work, but the basic rule is not to assign ORDER BY for a VIEW. At least, not in the outer fullselect.

Tom
0
 

Author Closing Comment

by:inversojvo
ID: 39728806
Guys, thank you a lot, you are great :)
0

Featured Post

Free Backup Tool for VMware and Hyper-V

Restore full virtual machine or individual guest files from 19 common file systems directly from the backup file. Schedule VM backups with PowerShell scripts. Set desired time, lean back and let the script to notify you via email upon completion.  

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Recursive SQL in UDB/LUW (you can use 'recursive' and 'SQL' in the same sentence) A growing number of database queries lend themselves to recursive solutions.  It's not always easy to spot when recursion is called for, especially for people una…
Recursive SQL in UDB/LUW (it really isn't that hard to do) Recursive SQL is most often used to convert columns to rows or rows to columns.  A previous article described the process of converting rows to columns.  This article will build off of th…
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …
Suggested Courses
Course of the Month13 days, 3 hours left to enroll

971 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question