Get data like in database order without sorting it - sql

I have a table which has ShipCountry, ShipCity and Freight column in SQL database. I tried to retrieve data from that table by using the below query.
Select ShipCountry from CountryDetails Group by ShipCountry
If i run this query i am getting results in Ascending order. Instead of this i need data in database order. How to achieve this through SQL query?
Note: If i run the below query, it will return the data in Database order. I am getting sorted data when i added group by clause in my query.
Select ShipCountry from CountryDetails

The use of group by for ordering is improper .. (group by is for aggregation function as min, max or count)
if you need a specific order use order by instead
Select ShipCountry from CountryDetails Order by ShipCountry
otherwise if want not order use simply
Select ShipCountry from CountryDetails
Remember that the values store in db have not a proper order ..and are selected in the sequence used for retrive the data.
Each time you need an order you must esplicitally use order by
for avoid "redundant values" .. use distinct and not group by eg:
Select distinct ShipCountry from CountryDetails

As already has been stated, what you describe might lead to unexpected results fro your end users.
Let's assume you have a table without any indexes or keys (A so-called heap). A heap pretty much can be compared to a phone book (yeah, I've been around for a while) consisting of hundreds of pages, on which information is randomly ordered. A heap is exactly that; A lot of randomly ordered data. Whenever you query from such a table, the query analyzer will do its very best to figure out what the fastest way to deliver the data is.
Such decisions from the query analyzer are guided by statistics; a collection of metrics about the data and the distribution thereof. SQL Server uses these statistics to figure out the cardinality (the uniqueness of values), and thus pick the fastest way to return data.
When you simply issue a SELECT * FROM myTable on a heap, those statistics will determine the order in which your data is returned. However, this also means that over time, the statistics will change, as more data flows into the table. This has the effect that the sort order of your data today is not necessarily the sort order in which the data is returned tomorrow, or even five minutes from now.
If that is fine with your end users, then a SELECT * FROM myTable is the right solution for you. But, if you absolutely need to have the data returned in a certain order, you should always implement an ORDER BY clause.

if you want to have the same database order in most cases if you have sorted by primary key it will be the same without ordering as you say:
here the id is the primary key, and if you can not use the primary key add an identity column and use it:
id name
1 elly
2 ahmad
3 joseph
4 omar

Related

SQL query does not return correct results

I am trying to filter between two dates on a SQL server from a PHP process.
This is the query:
select *
from webStocks
where FECHAMODIFICADO between '2020-06-03 17:16:02' and '2020-06-04 17:16:03'
ORDER BY webStocks.FECHAMODIFICADO DESC
This is the result:
The result is not what I want. In the table I have the following information and it should be the result.
What am I doing wrong in the query?:(
I'd try to make sure the date column actually contains 'timestamp' data type.
If it doesn't, the following code should fix it:
SELECT *
FROM webStocks
where CAST(FECHAMODIFICADO AS timestamp) BETWEEN '2020-06-03 17:16:02' AND '2020-06-04 17:16:03'
ORDER BY webStocks.FECHAMODIFICADO DESC
You can see more information about this kind of statements here.
(this solution is valid mostly for MySQL, but will probably work with either CAST or CONVERT statement with other SQL servers).
SQL tables represent unordered sets. That means that when you run a query with no ORDER BY, the results can be in any order -- and even in different orders on different runs.
In this case, you have an ORDER BY. But the column has duplicates. The same principle applies: rows with the same key value can be in any order -- and even in different orders on different runs.
So, you need to add a new key to capture the order that you want. It is not obvious from your data. But the results would at least be stable if you used:
ORDER BY webStocks.FECHAMODIFICADO DESC, CodeArticulo
It is also odd that your WHERE clause includes very specific times. But the data in these rows is all occurring at midnight. Usually midnight is not such an active time, if the time stamps represent human behavior.

Store data sorted into new table

Good afternoon all,
I have two columns that I am trying to sort into a table, memberid and then total spend. When I run the following query:
Select Memberid, totalspend
from Table
order by totalspend;
my data returns the way that I expect it to. When I try and run:
Select MemberID, TotalSpend
into SampleTable
from Table
order by TotalSpend
SQL does not retain the sort.
The research that I have done so far suggests that the select into statement should work but for some reason it it not. I have tried converting the Totalspend to a float, int or varchar and still no luck.
I need my data sorted so that I can perform calculations on the table based on top x rows.
I am currently using SQL Server 2017.
Thank you,
Richard
SQL does not retain the sort.
This is soooo true. SQL tables represent unordered sets. No ordering. Get it?
That said, you can sort of impose order on the data. Here are two methods:
You can define a primary key. The data is physically sorted on the data pages (in SQL Server) based on the primary key.
You can define an identity column. In conjunction with order by, the identity column will capture the ordering.
Strictly speaking these have no effect on the result set from a query on the table. Instead, they are methods for storing the ordering in the data.
What is true about tables being unordered is also true about result sets. So if you run:
Select MemberID, TotalSpend
from SampleTable;
The result set is unordered. That means that even with a primary key or an identity column or both, SQL Server can return the rows in whatever order it so desires. It can even return the data in different orders on different runs.
Fixing this is easy. If you want the data in a particular order, simply add the following to your query:
order by TotalSpend
If you have an index on the column, then the sorting would normally use the index (unless the data is very small), so very little overhead would be incurred.

how to resolve this - group by changes the Order of items in SQL Server

I'm using SQL server 2014,I'm fetching data from a view.The order of items is getting changed once i use Group by ,how can i get the order back after using this Group by,There is one date column,but its not saving any time,So i can't sort it based on date also..
How can I display the data in the same order as it displayed before using Group by?Anyone have any idea please help?
Thanks
Tables and views are essentially unordered sets. To get rows in a specific order, you should always add an ORDER BY clause on the columns you wish to order on.
I'm assuming you previously selected from the VIEW without an ORDER BY clause. The order in which rows are returned from a SELECT statement without an ORDER BY statement is undefined. The order you are getting them in, can change due to any number of reasons (eg some are listed here).
Your problem stems from the mistake you made on relying on the order from a SELECT from a VIEW without an ORDER BY. You should have had an ORDER BY clause in your SELECT statement to begin with.
How can I display the data in the same order as it displayed before using Group by?
The answer: You can't if your initial statement did not have an ORDER BY clause.
The resolution: Determine the order you want the resultset in and add an ORDER BY clause on those columns, both in your initial query and the version with the GROUP BY clause.
Maybe you can use the row_number() function without any OVER and ORDER BY keywords? This should be done in a sub-select and when you group the data in the outer SELECT, use the AVG() function on the numbered column and ORDER the result by this. The problem is, that when you group rows, the original rows disappear. That's kind if the purpose of GROUP BY. ;) Depending on what you GROUP BY, what you're asking might be logically impossible.
EDIT:
Found this solution Googling: http://blog.sqlauthority.com/2015/05/05/sql-server-generating-row-number-without-ordering-any-columns/
So you can number rows like this to maintain the order of rows from the table before you GROUP BY:
row_number() OVER (ORDER BY (SELECT 1))
The only way you can enforce a specific order is to explicitly use a ORDER BY clause. Otherwise the order of rows is not guaranteed (take a look at this article for more details) and the database engine will return the rows based on "as fast as it can" or "as fast as it can retrieve them from disk" rule. So, order can also vary between executions of the same query in the span of a few seconds.
When doing a DISTINCT, GROUP BY or ORDER BY, SQL Server automatically does a SORT of the data based on an index it uses for that query.
Looking at the execution plan of your query will show you what index (and implicitly columns in that index) is being used to sort the data.

SQL pagination based on last record retrieved

I need to implement pagination which is semi-resilient to data changing between paginations. The standard pagination relies on SQL's LIMIT and OFFSET, however offset has potential to become inaccurate as new data points are created or their ranking shifts in the sort.
One idea is to hold onto the last data point requested from the API and get the following elements. I don't really know SQL (we're using postgres), but this is my (certainly flawed) attempt at doing something like that. I am trying to store the position of the last element as 'rownum' and then use it in the following query.
WITH rownum AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY rank ASC, id) AS rownum
WHERE id = #{after_id}
FROM items )
SELECT * FROM items
OFFSET rownum
ORDER BY rank ASC, id
LIMIT #{pagination_limit}
I can see some issues with this, like if the last item changes significantly in rank. If anyone can think of another way to do this, that would be great. But I would like to confine it to a single DB query if possible since this is the applications most frequently hit API.
Your whole syntax doesn't quite work. OFFSET comes after ORDER BY. FROM comes before WHERE etc.
This simpler query would do what I think your code is supposed to do:
SELECT *
FROM items
WHERE (rank, id) > (
SELECT (rank, id)
FROM items
WHERE id = #{after_id}
)
ORDER BY rank, id
LIMIT #{pagination_limit};
Comparing the composite type (rank, id) guarantees identical sort order.
Make sure you have two indexes:
A multicolumn index on (rank, id).
Another one on just (id) - you probably have a pk constraint on the column doing that already. (A multicolumn index with leading id would do the job as well.)
More about indexes:
Is a composite index also good for queries on the first field?
If rank is not volatile it would be more efficient to parameterize it additionally instead of retrieving it dynamically - but the volatility of rank seems to be the point of your deliberations ...
I now think the best way to solve this problem is by storing the datetime of the original query and filtering out results after that moment on subsequent queries, thus ensuring the offset is mostly correct. Maybe a persistent database could be used to ensure that the data is at the same state it was when the original query was made.

SELECT DISTINCT without ordering the rows

I'm doing the following query:
SELECT DISTINCT column1, colum2 FROM table.... WHERE....
but I don't want that the result returned were in order.
How can I avoid that sql sort this rows?
They are not getting sort per se, they are just returning using whatever index is on your table or just scanning the whole table. If you want them sort randomly, then you need to explicitely say so on your query:
SELECT *
FROM (SELECT DISTINCT column1, colum2
FROM table....
WHERE....) A
ORDER BY NEWID()
FIDDLE DEMO
ORDER BY isn't required for SELECT DISTINCT (or anything else)...What kind of ordering are you seeing? It may just be that the data was ordered when it was entered into the system.
The select distinct has to identify duplicate rows. There are basically two ways to do this. One is to sort the data (which may be done implicitly using an index). Then duplicate rows appear next to each other. The other is to build a hash table. Duplicate rows appear in the same hash buckets.
For your query, SQL Server is choosing to sort the data. It happens to look like the data is being ordered. On a multi-threaded system, then the data might look sorted, but when you scroll through it, you'll find that the sorting is in chunks (as data is returned from each thread).