designedly big value in SQL - sql

Ok, I have to put null values last. The query should run under Oracle and MySQL.
I've already came up with
ORDER BY
CASE WHEN some_table.ord IS NULL THEN 9999999999 ELSE some_table.ord END
I should use value > max(some_table.ord) instead of 9999999999.
I think subquery to determine this value is too ugly here.
If this was C++ I can use some macro like INT_MAX for this purpose. Can you name its cross-DBMS SQL twin?
UPDATE
the question is if can I put something .. beautiful instead of 9999999999, so that query will work both in Oracle and MySQL,
not how to put null values last

Use an extra column for the null flag:
order by
case when some_table.ord is null then 2 else 1 end ,
some_table.ord
Or, if you have enough knowledge of the values that this column can take, just hard-code a number that is larger than anything in there:
order by coalesce(some_table.ord, 9999999999)

In Oracle, it's simply
ORDER BY some_table.ord NULLS LAST

Something like the following might work:
SELECT S.VAL1, S.VAL2, S.VAL3, COALESCE(S.ORD, O.MAX_ORD+1) AS ORD
FROM SOME_TABLE S,
(SELECT MAX(ORDER) AS MAX_ORD FROM SOME_TABLE) O
WHERE S.whatever = whichever AND
S.something <> something_else
ORDER BY ORD
Not sure if MySQL allows sub-queries in the FROM list. The idea here is to avoid the use of a magic value to handle the NULL case.
Share and enjoy.

Related

ORDER BY with column number in case

I have a select with the following order by:
ORDER BY 4 DESC, case when (5 is null ) then 1 else 2 end, 5 desc,10
However, apparently, the fifth column is used as the literal 5, unlike the other expressions:
A constant expression was encountered in the ORDER BY list, position 2.
What should I do here?
Thanks!
Use the actual column names! That way, any future changes to the columns in your select don't break your order by.
And if you don't believe me: https://sqlblog.org/2009/10/06/bad-habits-to-kick-order-by-ordinal
This is an all around bad idea. Use the column name no matter how long it is.It would be a maintenance nightmare otherwise.You should try to avoid using dynamic sql.

Creating new column using nvl

here is my problem. I have an inner query that is working fine, however when I pass the results to outer query I get an error. What I want to accomplish is this, on the outer query, I want to always check if this column (GCO_AD_KNOWLEDGE_TEST_SCORE ) has a value, if it has a value I want to alias it as psi score new column name, additionally if this column does not have a value, I want to check for the second column (PSI_OVERALL_SCORE) if it has a value I want to alias it as PSI Score (new column). anyone want to take stab at this, I will appreciate it.
SELECT
NVL ((CASE WHEN BB.GCO_AD_KNOWLEDGE_TEST_SCORE IS NOT NULL THEN BB.GCO_AD_KNOWLEDGE_TEST_SCORE, ) BB.PSI_OVERALL_SCORE) as PSI SCORE
else null
end
FROM(
SELECT
PARENT_PI_NUMBER,PI_CANDIDATE_NUM,REQUEST_LAST_MODIFIED_DT,Contest_number,
MAX(AA.GCO_AD_KNOWLEDGE_TEST_SCORE) KEEP (DENSE_RANK LAST ORDER BY AA.ARANK) MAX_GCO_AD_KNOWLEDGE_TEST_SCORE,
MAX(AA.PSI_OVERALL_SCORE) KEEP (DENSE_RANK LAST ORDER BY AA.ARANK) MAX_PSI_OVERALL_SCORE
FROM (
select
RANK() OVER (PARTITION BY PARENT_PI_NUMBER ORDER BY REQUEST_LAST_MODIFIED_DT) ARANK
,Contest_number,PARENT_PI_NUMBER,PI_CANDIDATE_NUM,PI_NUMBER,PSI_OVERALL_SCORE,GCO_AD_KNOWLEDGE_TEST_SCORE,REQUEST_LAST_MODIFIED_DT
from
WC_APPLICATION_EVENT_F
WHERE GCO_AD_KNOWLEDGE_TEST_SCORE != '10100'
--WHERE PI_CANDIDATE_NUM = '4639022'and GCO_AD_KNOWLEDGE_TEST_SCORE is not null
) AA
GROUP BY PARENT_PI_NUMBER,PI_CANDIDATE_NUM,REQUEST_LAST_MODIFIED_DT,Contest_number;
--ORDER By PARENT_PI_NUMBER,PI_NUMBER,REQUEST_LAST_MODIFIED_DT;
) BB;
Your inner query still has a semicolon at the end.
MX_GCO_AD_KNOWLEDGE_TEST_SCORE is 31 characters so isn't valid unless you're on 12cR2 (or higher) with long identifiers enabled.
Your nvl/case construction has parentheses and end in the wrong places and has a spare comma with nothing following it.
Your nvl/case are attempting to refer to the original GCO_AD_KNOWLEDGE_TEST_SCORE and PSI_OVERALL_SCORE columns, but those are not exposed by the inline view.
It sounds like you're trying to get:
COALESCE(BB.MX_GCO_AD_KNOWLEDGE_TEST_SCORE, BB.MX_PSI_OVERALL_SCORE) as PSI_SCORE
using the aliases from the inner query, which I've modified from MAX_ to MX_ to make the first one legal.
It's hard to tell if the inner query is actually right with data and expected results, but you said that it's doing what you want.

Access Count of Rows Where Field is not Null

I need to count rows where the value of Master.[Date BP] is not Null - any ideas how I would do this?
I tried this but it doesn't seem to work.
SELECT Master.[Date BP], Count(Master.[Date BP]) AS CountOfField,
FROM Master
GROUP BY Master.[Date BP];
SELECT Count([Date BP]) AS CountOfField
FROM Master
Using count is the right idea. You just need to remove the group by clause, as you want a single answer. Additionally, you have a redundant comma at the end of the select list:
SELECT Count(Master.[Date BP]) AS CountOfField
FROM Master
The above answers are correct. Just in case you may face other problems with other aggregate functions, aggregate functions in SQL will ignore the null value.
Reference: https://msdn.microsoft.com/en-us/library/ms173454.aspx

SQL Order By Except When You Don't

I want to retrieve a full table with some of the values sorted. The sorted values should all appear before the unsorted values. I though I could pull this off with a UNION but order by is only valid to use after unioning the table and my set of data isn't set up such that that is useful in this case. I want rows with a column value of 0-6 to show up sorted in DESC order and then the rest of the results to show up after that. Is there some way to specify a condition in the order by clause? I saw something that looked close to what I wanted to so but I couldn't get the equality condition working in sql. I'm going to try to make a query using WHEN cases but I'm not sure if there's a way to specify a case like currentValue <= 6. If anyone has any suggestions that would be awesome.
You could do something like this:
order by (case when currentValue <= 6 then 1 else 0 end) desc,
(case when currentValue <= 6 then column end) desc
The first puts the values you care about first. The second puts them in sorted order. The rest will be ordered arbitrarily.
Try this:
SELECT *
FROM yourdata
ORDER BY CASE WHEN yourColumn BETWEEN 0 AND 6 THEN yourColumn ELSE -1 End Desc
One RDBMS-agnostic solution would be to add a second field that takes the same value as the field you wish to sort when that field is less than or equal to six. Then just sort by that field.

nhibernate - sort null at end

Using NHibernate from C# and only HQL (not SQL) in a way that is compatible with MS SQL Server 2005/2008 (and preferably Oracle).
Is there a way to write the order by clause so that nulls will sort at the end of the query results while the non-null results will be sorted in ascending order?
Based on the answer to the question referenced by nickf the answer is:
select x from MyClass x order by case when x.MyProperty is null then 1 else 0 end, x.MyProperty
I don't know if this helps or not, but there's another question asking the same thing about how to do this with MySQL.
Perhaps the same logic could be applied to HQL?
edit: this got accepted, so apparently, yes it can.
Here's the accepted answer from that question (by Bill Karwin):
SELECT * FROM myTable
WHERE ...
ORDER BY CASE WHEN myDate IS NULL THEN 1 ELSE 0 END, myDate;
At one point I just gave up and fixed the sort order in my collection class.
Since I was just moving NULLs all I had to do was peel off the nulls at the beginning of the collection and append them to the end.
With a bet of cleaver coding, it can even be done on an array.
Nevertheless, that ORDER BY CASE is a cleaver and readable trick.