If i run a select query on a MS Sql database, without Order by clause, will it return the order of insertion?
I need to be sure that a specific row in my database has been inserted prior to another. By running a select all without any order by, this statement above would be true. I am not sure tough that the order of the rows returned is in fact the order in that they have been added to the database. All tests I made point in that direction and seem to confirm this assumption, but I was not able to find a official statement or confirmation of this anywhere.
I was able to solve the problem by using this:
select mycolumns, %%physloc%% as pl from mytable order by pl desc
Rows that have been written one after the other will have very similar values in this column, unless it has been written something totally different. In my case it solved the problem.
Related
I'm not an Oracle developer. We have a job with steps which retrieve data from Oracle and publish (update and insert) it into another database. The weird problem is in the select query which gives error
ORA-01427: single-row subquery returns more than one row
after investigating the query was
SELECT DISTINCT CUSTOMER, CUSTOMER_STATUS, CUST_ACCT_CREATION_DATE,.... FROM table_CUSTOMER
and when I remove certain columns from the query it gives me results with no problems, but unfortunately these columns is needed for other purposes.
How can these columns generate this error?
How? Because they don't make a distinct result set, that's how.
If you need to fetch a single row, apply WHERE clause to that query which will make sure that only one row is returned.
The simplest way to restrict number of rows is to use WHERE rownum = 1, but it'll return one, random row. Will it satisfy business rules? I don't know. Maybe; maybe not.
We don't have your tables nor data. But, if you could provide test case, someone might assist.
I have a difficult (if not impossible) problem to ask a solution for. I have an Oracle query, and I have to translate it to T-SQL syntax.
The query looks like this in Oracle:
__select_wrapper=select * from(
select rownum row_num, inner__c3p__query.*
from ({0}) inner__c3p__query)
where row_num>#offset and (row_num<=(#offset+#count) or (#count<1))
This comes from a properties file. Basically, this one line executes any SQL query, names the resultset "inner__c3p__query", and selects everything from it and also a rownum. Then, it filters the result by the rownum: >#offset and <=#offset + #count. So, practically, it executes any SQL query, and returns a limited rowset, e.g. from the 10th row to the 20th.
Now, my job is to transform this into T-SQL. I spent one and a half day looking up every possible idea, but so far, I haven't succeeded. I tried a great many things, neither of them worked. The problem is, I can't use ROW_NUMBER() function, because it requires at least one column in the OVER() clause, and I can't provide any, because the actual query is only determined at runtime.
Do you guys have any idea, or is it really impossible to do on the DB side?
Thanks in advance!
Gabe
While I have a lot of reservations about this kind of approach, especially wrt SQL Injection attacks, the following should work:
select * from(
select ROW_NUMBER() OVER(ORDER BY (Select NULL)) row_num,
inner__c3p__query.*
from ({0}) inner__c3p__query)
where row_num>#offset and (row_num<=(#offset+#count) or (#count<1))
Unfortunately, since the ordering column never changes, if you are trying to use this for paging, you cannot guarantee that the same row_num is always assigned to the same row in repeated executions.
ROW_NUMBER() only requires a column in the ORDER BY part (otherwise how do you order them?)
If the original was a random order then just pick a random column in the query (like the first one.) In an ORDER BY you can use column numbers... just use the first column or the number one.
ROW_NUMBER() OVER (ORDER BY 1)
When I do a simple query using Microsoft SQL Server Management Studio I would expect the rows to be in order based on the ID column which is my primary key column.
For the most part the rows are in order but every once in awhile it will go from 98,99,100,1035,1036,1037,101 but when it jumps around it is in groups not just a single row out of order. The rows are added to the database using a simple INSERT from a ColdFusion script.
Is there a reason this is happening? I can do a ORDER BY so it is readable but if there is something I am doing incorrectly to start with I would like to fix my error.
Let me know if any more information would help.
MS SQL Server makes no guarantee about the order in which records are actually stored internally. So you can't depend on records coming out in the order of the primary key. If you want to order your result set, then use ORDER BY with an appropriate column; it's what it was designed for.
This question already has answers here:
sql server 2008 management studio not checking the syntax of my query
(2 answers)
Closed 8 years ago.
I'm confused by an SQL query, and honestly, its one of those things that I'm not even sure how to google for. Thus StackOverflow.
I have what I think is a simple query.
SELECT Id
FROM Customer
WHERE Id IN (SELECT Id from #CustomersWithCancelledOrders)
Here's where I find the weirdness. There is no column called Id in the #CustomersWithCancelledOrders table variable. But there isn't an error.
What this results in is the Ids for all Customers. Every single one. Which obviously defeats the point of doing a sub-query in the first place.
It's like its using the Id column from the outer table (Customers), but I don't understand why it would do that. Is there ever a reason you would want to do that? Am I missing something incredibly obvious?
SQLFiddle of the weirdness. It's not the best SQL Fiddle, as I couldn't find a way to return multiple result sets on that website, but it demonstrates how I ran across the issue.
I suppose what I'm looking for is a name for the "feature" above, some sort of information about why it does what it does and what the incorrect query actually means.
I've updated the above question to use a slightly better example. Its still contrived, but its closer to the script I wrote when I actually encountered the issue.
After doing some reading on correlated subqueries, it looks like my typo (using the wrong Id column in the subquery) changes the behaviour of the subquery.
Instead of evaluating the results of the subquery once and then treating those results as a set (which was what I intended) it evaluates the subquery for every row in the outer query.
This means that the subquery evaluates to a set of different results for every row, and that set of results is guaranteed to have the customer Id of that row in it. The subquery returns a set consisting of the Id of the row repeated X number of times, where X is the number of rows in the table variable that is being selected from.
...
Its really hard to write down a concise description of my understanding of the issue. Sorry. I think I'm good now though.
It's intended behaviour because in a sub query you can access the 'outer queries' column names. Meaning you can use Id from Table within the Subquery and the query therefore thinks you are using Id.
That's why you should qualify with aliases or fully qualified names when working with sub queries.
For example; check out
http://support.microsoft.com/kb/298674
SELECT ID
FROM [Table]
WHERE ID IN (SELECT OtherTable.ID FROM OtherTable)
This will generate an error. As Allan S. Hanses said, in the subquery you can use colums from the main query.
See this example
SELECT ID
FROM [Table]
WHERE ID IN (SELECT ID)
The query is a correlated sub-query and is most often used to limit the results of the outer query based on a column returned by the sub query; hence the 'correlated'.
In this example the ID in the inner query is actually the ID from the table in the outer query. This makes the query valid but probably doesn't give you any useful results as it isn't actually correlating between the outer and inner queries.
I'm trying to use this query to delete the rows that are already on a linked server's Database:
GO
USE TAMSTest
GO
DELETE from [dbo].[Hour]
WHERE [dbo].[Hour].[InHour] = (SELECT [InHour]
FROM [TDG-MBL-005].[TAMSTEST].[dbo].[Hour])
GO
When there is only 1 row in the linked server's table, SELECT [InHour] FROM [TDG-MBL-005].[TAMSTEST].[dbo].[Hour] returns that single row and the DELETE works as expected. However, with multiple rows in the linked sever's table, it doesn't work since that part of the query returns mutiple rows as its result. How can I work around this?
If there is further information needed please ask, I need to get this done ASAP.
Thanks in advance,
Eton B.
Change your equal sign to an IN statement
DELETE from [dbo].[Hour]
WHERE [dbo].[Hour].[InHour] IN (SELECT [InHour]
FROM [TDG-MBL-005].[TAMSTEST].[dbo].[Hour])
The IN clause allows you to have multiple values in your WHERE clause, and can be used in subqueries as well. Here's more information.