Need to perform ORDER by Twice - sql

I want to sort according to date first and then if date is similar then according to id..How to do that in Informix/HSQL query?

SELECT FIELD1, FIELD2 FROM TABLE ORDER BY FIELD1 ASC, FIELD2 ASC
A good tutorial on this SQL ORDER BY

This should work:
SELECT * FROM Table
ORDER BY date, id;

Does
[rest of query] order by date, id
work?

Try this(adjusted to your needs):
SELECT * FROM table ORDER BY datecol ASC, id ASC

select * from (select * from tablename order by col1) AS T order by col2
(It's necessary to give an alias to the virtual table, hence "AS T")

select * from (select * from tablename order by col1) AS T order by col2
This works but is redundant and obtuse. Note the subquery (on "col1") becomes the secondary sort; the primary sort is the encompassing query. Some environments may require the "as T" aliasing of the subquery, but not all.
select * from tablename order by col2, col1
This does the same thing as above, with simple clarity
Or for a more realistic example:
select * from customers order by lastname, firstname

Related

Optimized way to select distinct records

I have a table in hive with 23 columns out of which 5 columns make up the composite primary keys.
what is the best optimized way to select all the distinct records from the table.
select *
from (select t.*
,count(*) over (partition by Col1,Col2,Col3,Col4,Col5) as cnt
from tablename t
) t
where t.cnt = 1
;
Use the group by statements with where statements where count(1)>=1 this will give you the distinct records based on your composite key.
Like
Select Col1,Col2,Col3,Col4,Col5,Count(1) from tablename group by Col1,Col2,Col3,Col4,Col5 having Count(1)>=1

how to avoid duplicating value with all fields in sql query

I have a query like this:
Select * from V_Receipt Where F_Exhibition='11000' order by F_Exhibitor_Name
When executed I get duplicate values, how can I resolve this.
You need to use DISTINCT but you will also have to explicitly define each field
SELECT DISTINCT field1, field2, field3 /* etc etc */
FROM V_Receipt
WHERE F_Exhibition = '11000'
ORDER BY F_Exhibitor_Name DESC
with cte
as
(select row_number(partition by feild 1 order by field1) as rnk,* from V_Receipt )
select * from cte where rnk=1;

How to replace a DISTINCT ON with GROUP BY in PostgreSQL 9?

I have been using the DISTINCT ON predicate and have decided to replace it with GROUP BY, mainly because it "is not part of the SQL standard and is sometimes considered bad style because of the potentially indeterminate nature of its results".
I am using DISTINCT ON in conjunction with ORDER BY in order to select the latest records in a history table, but it's not clear to me how to do the same with the GROUP BY.
What could be a general approach in order to move from one construct to the other one?
An example could be
SELECT
DISTINCT ON (f1, f2 ) *
FROM table
ORDER BY f1, f2, datefield DESC;
where I get the "latest" pairs of (f1,f2).
If you have a query like this:
select distinct on (col1) t.*
from table t
order by col1, col2
Then you would replace this with window functions, not a group by:
select t.*
from (select t.*,
row_number() over (partition by col1 order by col2) as seqnum
from table t
) t
where seqnum = 1;

Select top and bottom rows

I'm using SQL Server 2005 and I'm trying to achieve something like this:
I want to get the first x rows and the last x rows in the same select statement.
SELECT TOP(5) BOTTOM(5)
Of course BOTTOM does not exist, so I need another solution. I believe there is an easy and elegant solution that I'm not getting. Doing the select again with GROUP BY DESC is not an option.
Using a union is the only thing I can think of to accomplish this
select * from (select top(5) * from logins order by USERNAME ASC) a
union
select * from (select top(5) * from logins order by USERNAME DESC) b
Check the link
SQL SERVER – How to Retrieve TOP and BOTTOM Rows Together using T-SQL
Did you try to using rownumber?
SELECT *
FROM
(SELECT *, ROW_NUMBER() OVER (Order BY columnName) as TopFive
,ROW_NUMBER() OVER (Order BY columnName Desc) as BottomFive
FROM Table
)
WHERE TopFive <=5 or BottomFive <=5
http://www.sqlservercurry.com/2009/02/select-top-n-and-bottom-n-rows-using.html
I think you've two main options:
SELECT TOP 5 ...
FROM ...
ORDER BY ... ASC
UNION
SELECT TOP 5 ...
FROM ...
ORDER BY ... DESC
Or, if you know how many items there are in the table:
SELECT ...
FROM (
SELECT ..., ROW_NUMBER() OVER (ORDER BY ... ASC) AS intRow
FROM ...
) AS T
WHERE intRow BETWEEN 1 AND 5 OR intRow BETWEEN #Number - 5 AND #Number
Is it an option for you to use a union?
E.g.
select top 5 ... order by {specify columns asc}
union
select top 5 ... order by {specify columns desc}
i guess you have to do it using subquery only
select * from table where id in (
(SELECT id ORDER BY columnName LIMIT 5) OR
(SELECT id ORDER BY columnName DESC LIMIT 5)
)
select * from table where id in (
(SELECT TOP(5) id ORDER BY columnName) OR
(SELECT TOP(5) id ORDER BY columnName DESC)
)
EDITED
select * from table where id in (
(SELECT TOP 5 id ORDER BY columnName) OR
(SELECT TOP 5 id ORDER BY columnName DESC)
)
No real difference between this and the union that I'm aware of, but technically it is a single query.
select t.*
from table t
where t.id in (select top 5 t2.id from table t2 order by MyColumn)
or
t.id in (select top 5 t2.id from table t2 order by MyColumn desc);
SELECT *
FROM (
SELECT x, rank() over (order by x asc) as rown
FROM table
) temp
where temp.rown = 1
or temp.rown = (select count(x) from table)
Then you are out - doing the select again IS the only option, unless you want to pull in the complete result set and then throwing away everything in between.
ANY sql I cna think of is the same way - for the bottom you need to know first either how many items you have (materialize everything or use count(*)) or a reverse sort order.
Sorry if that does not suit you, but at the end.... reality does not care, and I do not see any other way to do that.
I had to do this recently for a very large stored procedure; if your query is quite large, and you want to minimize the amount of queries you could declare a #tempTable, insert into that #tempTable then query from that #tempTable,
DECLARE #tempTable TABLE ( columns.. )
INSERT INTO #tempTable
VALUES ( SELECT.. your query here ..)
SELECT TOP(5) columns FROM #tempTable ORDER BY column ASC -- returns first to last
SELECT TOP(5) columns FROM #tempTable ORDER BY column DESC -- returns last to first

Why doesn't SQL DISTINCT work with ORDER BY CAST?

Including DISTINCT to an SQL query that also uses ORDER BY CAST(thecolumn AS int) as shown here seems to remove that sorting functionality.
Any reason these cant work together?
(Using sqlite with the C api)
Thanks.
EDIT:
Started with -
sprintf(sql, "SELECT DISTINCT rowX FROM TableX Order By Cast(rowX As int) LIMIT 150 OFFSET %s;", Offset);
rowX is Type CHAR(5)
NOW:
sprintf(sql, "Select rowX FROM(Select Distinct rowX From TableX)t Order By Cast(rowX As int) LIMIT 150 OFFSET %s;", Offset);
I used the following with sqlite, and sorting worked fine:
Select Distinct thecolumn
From your_table
Order By Cast(thecolumn As int)
Have you tried putting the DISTINCT into a sub-query?
Select thecolumn
From
(
Select Distinct thecolumn
From your_table
) t
Order By Cast(thecolumn As int)
I would expect it to work that way.
One more way:
Select thecolumn
From
(
Select Distinct Cast(thecolumn As int) As thecolumn
From your_table
) t
Order By thecolumn
This is way super late, but the order by has to match the select list exactly so:
select distinct cast(column as int)
from table
order by cast(column as int)