PostgreSQL order by special char - sql

I have to sync two databases. The first one (source) run on Sybase and the second (dist) run on PostgreSQL. I make for each rows a comparaison to check if the row exist or not (comparaison of the pk). But, for a specific table, the pk is a varchar.
I make :
SELECT * FROM table ORDER BY 1;
The table output look like this on Sybase :
# | row 1
.. | row 2
1 | row 3
...
and on PostgreSQL :
.. | row 1
# | row 2
1 | row 3
So, the rows have not the same order. I would like to obtain the same output in PostgreSQL that my Sybase db (SQL Anywhere).
Any idea ?

If I understand you correctly you need this query :
WITH x(a) AS (SELECT * FROM table ORDER BY 1)
SELECT *
FROM x
ORDER BY a COLLATE "C";

Related

Where clause by only number-convertable rows

I have a table with 2 columns like this
COLNUM | COLSTR
---------------
1 | 001223
2 | 002234
3 | ds2-dd
4 | 003344
I would like to make query like this
SELECT * FROM TABLE WHERE CAST(COLSTR AS NUMBER) IN (1223,3344)
But since 4th row can not cast to number, query fails. I could create a view which would eliminate non-number-transformable rows, but I would like to make this with one query. How do I do it?
Oracle 11g.
Thanks.
I would suggest to use regular expression
SELECT * FROM TABLE WHERE REGEXP_LIKE(COLSTR,'^[0-9]$')

SQL Server ID reseed after deleltion of a middle record

i have a Table from which i delete records .
The problem is when i delete a certain record,its ID flies away too, so the ID order is no longer respected within the table.
What i want is a SQL Server Procedure to rearrange records after the deletion of one of them.
Example :
ID ID ID
1 1 1
2 I delete record 2, i want to have this ===> 2 and NOT this : 3
3 3 4
4 4 5
5
You don't want to do this. The id should be a field that has no meaning other than identifying a row. You might have other tables that refer to the id and they would break.
Instead, just recalculate a sequential value when you query the table:
select t.*, row_number() over (order by id) as seqnum
from t;

Oracle - SQL - Count multiple fields

Using Oracle 10G
Say for example I have a table with three fields in it, I'd like one query which selects the counts of each column where they are not null. Field name
----------------------------------
| strTest1 | strTest2 | strTest3 |
----------------------------------
I know how to get the count of each one individually:
select count(*) from tablename where strTest1 is not null
but I'd like to know if it's possible to do this within one query for all 3 fields.
Thanks
It sounds like you want:
SELECT COUNT(STRTEST1), COUNT(STRTEST2), COUNT(STRTEST3) FROM YOUR_TABLE

I DISTINCTly hate MySQL (help building a query)

This is staight forward I believe:
I have a table with 30,000 rows. When I SELECT DISTINCT 'location' FROM myTable it returns 21,000 rows, about what I'd expect, but it only returns that one column.
What I want is to move those to a new table, but the whole row for each match.
My best guess is something like SELECT * from (SELECT DISTINCT 'location' FROM myTable) or something like that, but it says I have a vague syntax error.
Is there a good way to grab the rest of each DISTINCT row and move it to a new table all in one go?
SELECT * FROM myTable GROUP BY `location`
or if you want to move to another table
CREATE TABLE foo AS SELECT * FROM myTable GROUP BY `location`
Distinct means for the entire row returned. So you can simply use
SELECT DISTINCT * FROM myTable GROUP BY 'location'
Using Distinct on a single column doesn't make a lot of sense. Let's say I have the following simple set
-id- -location-
1 store
2 store
3 home
if there were some sort of query that returned all columns, but just distinct on location, which row would be returned? 1 or 2? Should it just pick one at random? Because of this, DISTINCT works for all columns in the result set returned.
Well, first you need to decide what you really want returned.
The problem is that, presumably, for some of the location values in your table there are different values in the other columns even when the location value is the same:
Location OtherCol StillOtherCol
Place1 1 Fred
Place1 89 Fred
Place1 1 Joe
In that case, which of the three rows do you want to select? When you talk about a DISTINCT Location, you're condensing those three rows of different data into a single row, there's no meaning to moving the original rows from the original table into a new table since those original rows no longer exist in your DISTINCT result set. (If all the other columns are always the same for a given Location, your problem is easier: Just SELECT DISTINCT * FROM YourTable).
If you don't care which values come from the other columns you can use a (bad, IMHO) MySQL extension to SQL and do:
SELECT * FROM YourTable GROUP BY Location
which will give a result set with one row per location and values for the other columns derived from the original data in an undefined fashion.
Multiple rows with identical values in all columns don't have any sense. OK - the question might be a way to correct exactly that situation.
Considering this table, with id being the PK:
kram=# select * from foba;
id | no | name
----+----+---------------
2 | 1 | a
3 | 1 | b
4 | 2 | c
5 | 2 | a,b,c,d,e,f,g
you may extract a sample for every single no (:=location) by grouping over that column, and selecting the row with minimum PK (for example):
SELECT * FROM foba WHERE id IN (SELECT min (id) FROM foba GROUP BY no);
id | no | name
----+----+------
2 | 1 | a
4 | 2 | c

How to select 10 rows below the result returned by the SQL query?

Here is the SQL table:
KEY | NAME | VALUE
---------------------
13b | Jeffrey | 23.5
F48 | Jonas | 18.2
2G8 | Debby | 21.1
Now, if I type:
SELECT *
FROM table
WHERE VALUE = 23.5
I will get the first row.
What I need to accomplish is to get the first and the next two rows below. Is there a way to do it?
Columns are not sorted and WHERE condition doesn't participate in the selection of the rows, except for the first one. I just need the two additional rows below the returned one - the ones that were entered after the one which has been returned by the SELECT query.
Without a date column or an auto-increment column, you can't reliably determine the order the records were entered.
The physical order with which rows are stored in the table is non-deterministic.
You need to define an order to the results to do this. There is no guaranteed order to the data otherwise.
If by "the next 2 rows after" you mean "the next 2 records that were inserted into the table AFTER that particular row", you will need to use an auto incrementing field or a "date create" timestamp field to do this.
If each row has an ID column that is unique and auto incrementing, you could do something like:
SELECT * FROM table WHERE id > (SELECT id FROM table WHERE value = 23.5)
If I understand correctly, you're looking for something like:
SELECT * FROM table WHERE value <> 23.5
You can obviously write a program to do that but i am assuming you want a query. What about using a Union. You would also have to create a new column called value_id or something in those lines which is incremented sequentially (probably use a sequence). The idea is that value_id will be incremented for every insert and using that you can write a where clause to return the remaining two values you want.
For example:
Select * from table where value = 23.5
Union
Select * from table where value_id > 2 limit 2;
Limit 2 because you already got the first value in the first query
You need an order if you want to be able to think in terms of "before" and "after".
Assuming you have one you can use ROW_NUMBER() (see more here http://msdn.microsoft.com/en-us/library/ms186734.aspx) and do something like:
With MyTable
(select row_number() over (order by key) as n, key, name, value
from table)
select key, name, value
from MyTable
where n >= (select n from MyTable where value = 23.5)