Why different sequence is observed for same SQL query on different DBMS? - sql

How does ORDER BY work when there are multiple rows with the same name?
I executed a query:
SELECT * FROM XYZ ORDER BY NAME;
On Oracle I get the following result:
Name
Uid
OwnerId
Test123
QuuNWWzUJKmZPC
iotNmQNGJKmZPC
Test123
NULL
NULL
On SQL Server I get the following result
Name
Uid
OwnerId
Test123
NULL
NULL
Test123
QuuNWWzUJKmZPC
iotNmQNGJKmZPC
Why is a different sequence shown? In Oracle the row with NULL appears 2nd whereas in SQL Server it appeared 1st. Is there any default behavior for each DBMS?
Is there any way to make SQL Server's result look like Oracle's?

An unordered result set is delivered with a non-deterministic ordering and it is possible that the order can change with every execution of the query.
If you apply an ORDER BY clause that defines a total ordering of the result set then that result set will be delivered in a deterministic ordering and the output will be identical with every execution of the query (assuming the underlying data set is unchanged).
If you apply an ORDER BY clause that defines a partial ordering of the result set then the results set will be partly ordered and partly non-deterministic.
For example, if you have the data set:
Name
Value
Alice
1
Beryl
2
Beryl
3
Alice
4
Alice
5
Beryl
6
and you use:
SELECT *
FROM table_name
ORDER BY name, value
Then that defines a total ordering of the result set such that it will be initially ordered by name, which defines a partial ordering, and then, within each set of rows with the same name, will be ordered by the value and the values are unique. This outputs:
Name
Value
Alice
1
Alice
4
Alice
5
Beryl
2
Beryl
3
Beryl
6
If you do not define a total ordering:
SELECT *
FROM table_name
ORDER BY name
Then the rows will be ordered by name but within the set of rows with the same names the individual rows can be in ANY order and this is a partial order and could output:
Name
Value
Alice
5
Alice
4
Alice
1
Beryl
3
Beryl
6
Beryl
2
but equally could output:
Name
Value
Alice
5
Alice
1
Alice
4
Beryl
6
Beryl
2
Beryl
3
Is there any way to make SQL Server's result look like Oracle's?
Do not apply a partial ordering; add columns to your ORDER BY clause to make it a total ordering and then the RDBMSes should output the result set in the same order.
SELECT *
FROM XYZ
ORDER BY
NAME ASC,
UID ASC NULLS LAST;

Related

How to select last element for each ID

I would like select some elements from the last id
Here an example that I have :
id money
1 200
1 150
1 500
3 50
4 40
4 300
5 110
Here what I would like :
1 500
3 50
4 300
5 110
So like you can see, I took last id and the money who corresponds.
I tried to do a group by id order by id descending with limit 1. But limit 1 is not available in proc sql from sas and it doesn't work.
Thanks in advance
Unlike SAS datasets, SQL tables represent unordered sets. In your case, it looks like you want the maximum value in the second column, in which case you can use aggregation:
proc sql;
select id, max(money)
from t
group by id;
If you actually mean the last row per id based on the ordering in the SAS dataset, I would suggest using a data step instead.

Order grouped table by id user sql

I want to order a grouped statement using as reference the number choosen by an specific user.
SELECT *
FROM likes
WHERE /**/
GROUP BY type
TABLE
id_user type
1420 1
1421 3
1422 3
1424 7
1425 4
1426 2
1427 1
expected result (at the end what user 1425 choosed)
1
2
3
7
4 //choosen by id_user 1425
I want to put the last row with the number choosed by the user. i just cant figure that out
You can aggregate and use a conditional max for ordering, like so:
select type
from likes
group by likes
order by max(case when id_user = 1425 then 1 else 0 end), type
If any row for the given type has an id_user that matches the chosen value, the conditional max returns 1, wich puts it last in the resultset. The second ordering criteria break the ties for groups that do not fulfill the condition.
If you are running MySQL, you can simplify the order by clause a little:
order by max(id_user = 1425), type

BigQuery INSERT SELECT results in random order of records?

I used standard SQL to insert data form one table to another in BigQuery using Jupyter Notebook.
For example I have two tables:
table1
ID Product
0 1 book1
1 2 book2
2 3 book3
table2
ID Product Price
0 5 book5 8.0
1 6 book6 9.0
2 4 book4 3.0
I used the following codes
INSERT test_data.table1
SELECT *
FROM test_data.table2
ORDER BY Price;
SELECT *
FROM test_data.table1
I got
ID Product
0 1 book1
1 3 book3
2 2 book2
3 5 book5
4 6 book6
5 4 book4
I expected it appears in the order of ID 1 2 3 4 5 6 which 4,5,6 are ordered by Price
It also seems that the data INSERT and/or SELECT FROM display records in a random order in different run.
How do I control the SELECT FROM output without including the 'Price' column in the output table in order to sort them?
And this happened when I import a csv file to create a new table, the record order is random when using SELECT FROM to display them.
The ORDER BY clause specifies a column or expression as the sort criterion for the result set.
If an ORDER BY clause is not present, the order of the results of a query is not defined.
Column aliases from a FROM clause or SELECT list are allowed. If a query contains aliases in the SELECT clause, those aliases override names in the corresponding FROM clause.
So, you most likely wanted something like below
SELECT *
FROM test_data.table1
ORDER BY Price DESC
LIMIT 100
Note the use of LIMIT - it is important part - If you are sorting a very large number of values, use a LIMIT clause to avoid resource exceeded type of error

Why does SELECT TOP 1 . . . ORDER BY return the second row in the table?

When I select all rows with the query:
SELECT *
FROM AFT_Contacts
ORDER BY Tries
I see the result:
ID Name Area Phone Status Tries
------------------------------------------------------
117970 Adam One 1111111111 New 0
117971 Brian Two 2222222222 New 0
117972 Colin Three 3333333333 New 0
117973 David Four 4444444444 New 0
117974 Edward Five 5555555555 New 0
117975 Frank Six 6666666666 New 0
But the query:
SELECT TOP 1 *
FROM AFT_Contacts
ORDER BY Tries
Returns:
ID Name Area Phone Status Tries
-----------------------------------------------------
117971 Brian Two 2222222222 New 0
Why does it not return Adam's details as they are first in the table?
In relational databases tables have no inherent order. The ORDER BY you give is not distinct over all records, in fact it's the same over all records. So the order in which results are returned is still not deterministic and unpredictable. And therefor the top 1 returns an unpredictable row.
You say "Adam's details are first in the table", this is simply not true; records in a table are stored without any order. If you select without an order by or (as in your case) the order by is not deterministic the returned order is arbitrary.

how to select one tuple in rows based on variable field value

I'm quite new into SQL and I'd like to make a SELECT statement to retrieve only the first row of a set base on a column value. I'll try to make it clearer with a table example.
Here is my table data :
chip_id | sample_id
-------------------
1 | 45
1 | 55
1 | 5986
2 | 453
2 | 12
3 | 4567
3 | 9
I'd like to have a SELECT statement that fetch the first line with chip_id=1,2,3
Like this :
chip_id | sample_id
-------------------
1 | 45 or 55 or whatever
2 | 12 or 453 ...
3 | 9 or ...
How can I do this?
Thanks
i'd probably:
set a variable =0
order your table by chip_id
read the table in row by row
if table[row]>variable, store the table[row] in a result array,increment variable
loop till done
return your result array
though depending on your DB,query and versions you'll probably get unpredictable/unreliable returns.
You can get one value using row_number():
select chip_id, sample_id
from (select chip_id, sample_id,
row_number() over (partition by chip_id order by rand()) as seqnum
) t
where seqnum = 1
This returns a random value. In SQL, tables are inherently unordered, so there is no concept of "first". You need an auto incrementing id or creation date or some way of defining "first" to get the "first".
If you have such a column, then replace rand() with the column.
Provided I understood your output, if you are using PostGreSQL 9, you can use this:
SELECT chip_id ,
string_agg(sample_id, ' or ')
FROM your_table
GROUP BY chip_id
You need to group your data with a GROUP BY query.
When you group, generally you want the max, the min, or some other values to represent your group. You can do sums, count, all kind of group operations.
For your example, you don't seem to want a specific group operation, so the query could be as simple as this one :
SELECT chip_id, MAX(sample_id)
FROM table
GROUP BY chip_id
This way you are retrieving the maximum sample_id for each of the chip_id.