SQL Framing Query Problem - sql

I am running a SQL query that only returns a portion of the entire data. In other words, the data is 'framed.' I have an 'ORDER(ORDER BY' part and for whatever reason, that part isn't working all of the time. Sometimes I get what I expect, and other times I don't.
The query:
SELECT
*
FROM
(
SELECT
ROW_NUMBER() OVER(ORDER BY [datetime] DESC, timeMicroSec DESC) AS rowNum,
...
FROM
...
WHERE
...
) AS TempTbl
WHERE
rowNum BETWEEN #startRow AND #endRow;
The whole data query works when it is not framed and I use an 'ORDER BY' clause at the end. In the image below, the [datetime] column and the [timeMicroSec] column are joined with string concatenation.
As you can see, the ordering is all messed up. Any help would be appreciated.

When you cast a DateTime as a Varchar, it changes the way that SQL Server will order the column. It will no longer order it chronologically, but instead as just a plain old string.
If the data type is a DateTime, you would get the following descending sort order:
01/11/2011
02/22/2010
The first date is later chronologically... but if the data type is a Varchar... it would be sorted as:
02/22/2010
01/11/2011
Because the string "02" comes after "01"... the actual date value doesn't matter at this point. When you concatenate your date with timeMicroSec, you change the sorting to a Varchar sort.
Like the others said... if you order by RowNum instead of by your concatenated string, you will get a chronological order.

ORDER BY rowNum
as the last part of your query will fix your problem.

Related

A constant expression was encountered in the ORDER BY list, position 1

I tried to concat two string using sql query. Below is my code which is not working.
SELECT TOP 100 CONCAT('James ','Stephen') AS [Column1]
FROM [dbo].[ORDERS]
Group BY ()
ORDER BY CONCAT('James ','Stephen') ASC
If I use [Column1] instead of CONCAT('James ','Stephen') in Order by clause, it seems working.
SELECT TOP 100 CONCAT('James ','Stephen') AS [Column1]
FROM [dbo].[ORDERS]
Group by ()
ORDER BY [Column1] ASC
Can anyone explain me, why did not the first query work?
ORDER BY clause is to be used with columns from underlyring tables. You cannot order by constants.
This is explained in the documentation
Specifies a column or expression on which to sort the query result
set. A sort column can be specified as a name or column alias, or a
nonnegative integer representing the position of the column in the
select list.
ORDER BY documentation
Note that you can use an expression, such as ORDER BY CONCAT(field1, field2), but it makes no sense to try to sort by a hard coded string which would obviously be the same for every record.
You can get around this by referencing the alias, but this is not very useful.
From documentation
A sort column can be specified as a name or column alias, or a nonnegative integer representing the position of the column in the select list.
Multiple sort columns can be specified. Column names must be unique. The sequence of the sort columns in the ORDER BY clause defines the organization of the sorted result set. That is, the result set is sorted by the first column and then that ordered list is sorted by the second column, and so on.
However in first query you not specified neither a name or column alias nor position of the column in select list

Strange behaviour of SQL Server query

I have a query in a validation stored procedure. It goes something like this:
SELECT *
FROM Table1
WHERE batchID IN (SELECT id FROM #tempIds)
AND CAST(field1 AS DATE) > CAST(field2 AS DATE)
Both field1 and field2 have valid dates, i.e. doing IdDate on field1/2 returns 1.
The #tempIds table only has one column ID and contains only one row.
When I run the above query, I get this error:
Unable to convert varchar to date
But instead of selecting batch ids from temp table if I put hard-coded ID from the same temp table it works.
Any ideas what could be the issue?
The problem is that you are using varchar to store date (or datetime) values.
Choosing the correct data type for your columns would save you from a lot of problems, this one included. For detailed information, read Aaron Bertrand's Bad habits to kick : choosing the wrong data type.
Now, to address our conversation in the comments - SQL Server does not guarantee the order on which the conditions in the where clause are evaluated. This means that even if all the "date" strings in both your columns are convertible to date values for the specific batchID, you only need one wrong value in one of the columns to raise the "Unable to convert varchar to date" error.
This also means that even if you where to write your query the way Larry B suggested in his answer (now deleted - so for the sake of future readers - this was his suggestion:)
SELECT *
FROM Table1
WHERE batchID IN (SELECT id FROM #tempIds)
AND ISDATE(field1) = 1
AND ISDATE(field2) = 1
AND CAST(field1 AS DATE) > CAST(field2 AS DATE)
There is no guarantee that the last condition (cast(field1 as date) > cast(field2 as date)) will be evaluated after the isdate(field1)=1 condition.
The correct thing to do is to fix the problem - change the data types of the columns to the correct data type.
Assuming that can't be done (if you have no control over the structure of the database, for instance) - you can do a couple of things:
Find all the places where the values in field1 and in field2 can't be converted to dates and fix them. Consider adding a check constraint to validate that the values of these columns can be converted to date (assuming you can).
Separate your query into 2 parts:
;With cte as
(
SELECT *
FROM Table1
WHERE batchID IN (SELECT id FROM #tempIds)
AND ISDATE(field1) = 1
AND ISDATE(field2) = 1
)
SELECT *
FROM cte
WHERE CAST(field1 AS DATE) > CAST(field2 AS DATE)
This will eliminate the error, since you are only casting values where the ISDATE function already returned 1, but might not return some rows you want back, if the value if either field1 or field2 is wrong in these rows.

SQL Order By while ignoring leading characters

Im looking for some help with regards to ordering by a numeric value but the numeric values have leading chars (-).
For example
Column Order #
---5
--8
-6
A simple ORDER BY Order# DESC gives me an unordered output. How do you ignore the leading chars when sorting data such as the Order # above?
Using the H2 database syntax and functions, and a table declared as:
create table foo(bar varchar(10));
with the rows:
'---2'
'--3'
'-1'
the following query:
select bar from foo
order by cast (replace(bar, '-') as int);
gives me the results:
BAR
-1
---2
--3
which seems to be what you're after.
Disclaimer: this is possibly not the best way to do this, since the computed value is not indexed. For just ordering a reasonably-sized result set it doesn't matter.
The solution I came up with is similar to the answer given,
I can just cast the column data to an int and sort it the way ie
ORDER BY CAST((ColumnName) AS INT) DESC;
this sucessfully ignores the leading chars and sorts it by the numbers

Find most recent date in a table using HIVE

I just need to make a simple query of a table on a MapR cluster in that I want to know what the date is of the most recent record in the table. Dates are in a 'report_date' column in string format. I tried the following query without success:
select max(report_date) from partition.table_name
I know the second part of the statement works. Is there something wrong with the first part?
Thanks,
A
Your date column datatype is string hence the max function doesnt produce the output as desired.
for example : string column with values 1,2,3,4 and when you run max(column) you wont get the output as 4 , since max doesnt work on string datatype.
Try changing your datatype to DATE or TIMESTAMP , Which should work.
OR
if changing datatype is not possible then try,
If there is an auto incrementing ID column in the table or any column like so , then
select report_date from table_name order by ID desc.
This should provide you the max date sting.

SQL statement to get largest ID from database column

I have an ID column which it supposed to set to auto-increment but I forgot to set in when creating the database. Let's say the ID is from 1 - 20. I used the select Max() Sql statement to get the largest ID:
SELECT MAX(id) FROM Table_Name;
It supposed to return me 20. However, it returns me 9. I also realized that the id column in database is jumbled up. It starts from 1,2 then skips to 9,10 - 20 then back to 3 - 8. And 8 appears to be the last row and I think that's where the 9 comes from. My id in database is varchar() data type.
So, is there any way to amend my Sql statement to get the largest id in a list of sorted id?
Thanks in advance.
The issue is likely that the ID column is a varchar field, so 9 is greater than 10.
select max(convert(int, id)) from Table
Your column is a character type, not a numeric type, which explains everything you're seeing.
Try casting it to numeric:
select max(cast(id as signed)) from table
You haven't said which database you are using, so the syntax may vary to achieve the cast - consult online docs for your database.
Try this:
SELECT TOP 1 Id FROM Table ORDER BY Convert(INT, id) DESC