I have column data like this in my db
data
-----
1
2
A
3
4
B
I have below nls settings in place
SELECT * From NLS_SESSION_PARAMETERS;
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY AMERICA
NLS_ISO_CURRENCY AMERICA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE AMERICAN
NLS_SORT BINARY
NLS_COMP BINARY
When I query the db for **select data from <mytable> order by data ** I am getting the result as below
data
-----
1
2
3
4
A
B
The same query via hibernate is giving the results with alphabets first and numeric later
data
-----
A
B
1
2
3
4
But, I want column to be displayed with numbers first and alphabets later via hibernate
data
------
1
2
3
4
A
B
Can someone help me with this.
You can use regularexpressions to sort in such a way,
select data from <mytable> order by REGEXP_REPLACE(data ,'[^0-9]'), REGEXP_REPLACE(data ,'[0-9]')
That depends on NLS_SORT parameter's value. For example, in my database it is set to CROATIAN and the result is what you wanted:
SQL> select * From nls_session_parameters where parameter = 'NLS_SORT';
PARAMETER VALUE
-------------------- --------------------
NLS_SORT CROATIAN
SQL> with test (data) as
2 (select '1' from dual union all
3 select '2' from dual union all
4 select 'A' from dual union all
5 select '3' from dual union all
6 select '4' from dual union all
7 select 'B' from dual
8 )
9 select data
10 from test
11 order by data;
D
-
A
B
1
2
3
4
6 rows selected.
However, in your database, NLS_SORT = BINARY. Let's try it:
SQL> alter session set nls_sort = 'BINARY';
Session altered.
SQL> with test (data) as
2 (select '1' from dual union all
3 select '2' from dual union all
4 select 'A' from dual union all
5 select '3' from dual union all
6 select '4' from dual union all
7 select 'B' from dual
8 )
9 select data
10 from test
11 order by data;
D
-
1
2
3
4
A
B
6 rows selected.
SQL>
Right; the wrong result.
Therefore, modify NLS_SORT, if that's an option. See valid values by
SQL> select * From v$nls_valid_values where parameter = 'SORT';
PARAMETER VALUE ISDEP
-------------------- -------------------- -----
SORT BINARY FALSE
SORT WEST_EUROPEAN FALSE
SORT XWEST_EUROPEAN FALSE
SORT GERMAN FALSE
<snip>
I believe one of the two options below should work,
Use NLSSORT function in the order by clause explicitly.
select * from my_table order by NLSSORT(data,'NLS_SORT=BINARY');
Create a function based index on the column,
create index mytable_nlssort_index on my_table(nlssort(data, 'nls_sort=''BINARY'''))
Use the query as below when the column is indexed.
select data from my_table order by data;
Related
Employee has multiple versions of addresses and given addresses are being duplicate needs to be removed and replaced with single unique address row and update parent table with newly inserted address id reference in optimal way .
CREATE TABLE address (adr_id, ver_id, address) AS
SELECT 1, 1, 'newYork' FROM DUAL UNION ALL
SELECT 1, 2, 'newYork' FROM DUAL UNION ALL
SELECT 1, 3, 'newYork' FROM DUAL UNION ALL
SELECT 4, 1, 'Washington' FROM DUAL UNION ALL
SELECT 4, 2, 'Washington' FROM DUAL;
CREATE TABLE employee (emp_id,adr_id,ver_id,) AS
SELECT 100,1, 1 FROM DUAL UNION ALL
SELECT 200,1, 2 FROM DUAL UNION ALL
SELECT 300,1, 3 FROM DUAL UNION ALL
SELECT 400,4, 1 FROM DUAL UNION ALL
SELECT 500,4, 2 FROM DUAL;
Before
employee
id | adr_id | ver_id
100 1 1
200 1 2
300 1 3
400 4 1
500 4 2
Address
adr_id | ver_id | address
1 1 newYork
1 2 newYork
1 3 newYork
4 1 Washington
4 2 Washington
Expected After
Address
adr_id | ver_id | address
11 0 newYork
12 0 Washington
employee
id | adr_id | ver_id
100 11 1
200 11 2
300 11 3
400 12 1
500 12 2
Note: There is foreign key constraint between Employee and Address table with composite key comprising of adr_id & ver_id
This is being done using stored procedure but its too slow is there any parallel processing can be done here by some way?
I have a strange behaviour for the following query containing a regular expression:
SELECT COALESCE(lang.TITLE, ids.message_id) AS TEXT,
ids.message_id
FROM
(SELECT
CASE
WHEN regexp_instr(messages.NR, '[a-z]{2}[[:space:],_-]\d+[-_]\d{2,6}') > 0
THEN regexp_substr(messages.NR, '\d+')
ELSE messages.NR
END AS message_id
FROM
( SELECT 'GB 28647854-04' AS NR FROM dual
UNION
SELECT 'GB 5310031-05' AS NR FROM dual
UNION
SELECT '9184' AS NR FROM dual
) messages
) ids,
LOCAL_TITLES lang
WHERE ids.message_id = '' || lang.NUMBER_NO(+);
The LOCAL_TITLES contains the following entries:
5310031 | Some localized Text
9184 | Another Text
So the expected query result should be:
28647854 | 28647854
Some localized Text | 5310031
Another Text | 9184
This works well, when the query runs via SQL Developer. Also I have a (Unit-/Integration-) Test for my DAO, which runs this query returning the expected result.
My problem: when the query is executed by the running web application, then the regex does not find the numeric id. Instead, the actual query result is
GB 28647854-04 | GB 28647854-04
GB 5310031-05 | GB 5310031-05
Another Text | 9184
Do you have an idea, why the regular expression behaves differently, when it's coming from the web application?
Your regular expression is looking for lower-case characters with the [a-z] pattern. Your dual-generated data has upper-case GB, so they don't match, with default case-sensitive settings, at least in my locale:
alter session set nls_sort = 'BINARY';
SELECT
CASE
WHEN regexp_instr(messages.NR, '[a-z]{2}[[:space:],_-]\d+[-_]\d{2,6}') > 0
THEN regexp_substr(messages.NR, '\d+')
ELSE messages.NR
END AS message_id
FROM
( SELECT 'GB 28647854-04' AS NR FROM dual
UNION
SELECT 'GB 5310031-05' AS NR FROM dual
UNION
SELECT '9184' AS NR FROM dual
) messages;
MESSAGE_ID
--------------
9184
GB 28647854-04
GB 5310031-05
If you make the session case-insensitive they do:
alter session set nls_sort = 'BINARY_CI';
SELECT
CASE
WHEN regexp_instr(messages.NR, '[a-z]{2}[[:space:],_-]\d+[-_]\d{2,6}') > 0
THEN regexp_substr(messages.NR, '\d+')
ELSE messages.NR
END AS message_id
FROM
( SELECT 'GB 28647854-04' AS NR FROM dual
UNION
SELECT 'GB 5310031-05' AS NR FROM dual
UNION
SELECT '9184' AS NR FROM dual
) messages;
MESSAGE_ID
--------------
9184
28647854
5310031
You can also make it case-insensitive just within each regex call:
SELECT
CASE
WHEN regexp_instr(messages.NR, '[a-z]{2}[[:space:],_-]\d+[-_]\d{2,6}', 1, 1, 0, 'i') > 0
THEN regexp_substr(messages.NR, '\d+', 1, 1, 'i')
ELSE messages.NR
END AS message_id
...
Or just expand the character class:
WHEN regexp_instr(messages.NR, '[a-zA-Z]{2}[[:space:],_-]\d+[-_]\d{2,6}') > 0
or
WHEN regexp_instr(messages.NR, '[[:alpha:]]{2}[[:space:],_-]\d+[-_]\d{2,6}') > 0
Some of your sessions are being created with BINARY_CI (or some other case-insensitive) linguistic comparison settings, but your 'web application' setting is not. That may be down to the locale being used for each, so changing the application locale could also fix the discrepancy; but making the pattern more logical is probably better.
More specifically in your case (having looked at your profile), if your locale is Germany then your NLS_SORT with be German, which behaves the same as BINARY_CI does for me with a UK locale. Presumably your SQL Developer and unit test is being run with German settings, and your web app is not, either because of its own defaults or by design.
Read more about "SQL Regular Expressions in a Multilingual Environment" in the documentation.
I have below records in table.
col1 col2 col3
------------------------
1 Abc IN
2 DEF CA
3 Xyz IN
4 Cae CA
5 Pty IN
6 Zwe DE
7 Zwf US
Here User sends an Input like IN or CA or DE etc. User input has to be mapped against col3. Now I need to query all the records from the table but the records matching the user input (IN or CA or DE) should appear first in the list then all other records should appear. How can I do it using hibernate criteria?
I need the results in below the order if user sends IN as an input.
1 Abc IN
5 Pty IN
3 Xyz IN
2 DEF CA
4 Cae CA
6 Zwe DE
7 Zwf US
You could try to use ORDER BY CASE construct:
order by case when <your entity>.col3 = :parameter then '0' else '1' end asc
There are two ways to solve this problem:
1. Create two queries one with equal to another with not equal to and all results for both in single list.
2. If you don't want to query database twice then you have to write algo in java that will remove elements for your input from list and add it another list and after iteration add remaining list at the end.
try the case ... when statements:
select *, ( case when col3=:input then '0' | col3 else col3 end) as sorter from table order by sorter asc
not sure, if it works, but if it does it would be exactly what you want
Here is sample table data which is dynamic.
ColId Name JobId Instance
1 aaaaaaaaa 1 2dc757b
2 bbbbbbbbb 1 2dc757b
3 aaaaaaaaa 1 010dbb8
4 bbbbbbbbb 1 010dbb8
5 bbbbbbbbb 1 faa2733
6 aaaaaaaaa 1 faa2733
7 aaaaaaaaa 1 bc13d69
8 aaaaaaaaa 1 9428f4d
I want output like
ColId Name JobId Instance
1 aaaaaaaaa 1 2dc757b
3 aaaaaaaaa 1 010dbb8
5 bbbbbbbbb 1 faa2733
7 aaaaaaaaa 1 bc13d69
8 aaaaaaaaa 1 9428f4d
What should be the JPA query so that I can retrieve entire row having only single 'Instance'(there is no max min condition involved).
I need one row for each 'Instance' value
FROM table t GROUP BY t.instance should suit your needs.
Something like JPQL "Select entity from Entity entity where entity.id in (select min(subinstance.id) from Entity subinstance group by subinstance.instance)"
Functions like count, min, avg etc are allowed over columns not included in the group by statement, so any such should work if it returns a single id value from the grouping.
Im using an odbc-jdbc bridge in my project and I need select 2 pieces of data from the database and save the data to 2 variables on the java side of my application. Here is an example of my table.
SITE_ID ------- DEV_ID ------- SCHEDULE_TIME ------- VALUE_ENUM ------- IDX
---------------------------------------------------------------------------
1 3000 09:30:00 1 1
1 3000 11:30:00 0 2
1 3000 12:00:00 1 3
1 3000 14:00:00 0 4
1 3000 18:30:00 1 5
1 3000 20:30:00 0 6
1 4000 05:00:00 1 1
1 4000 13:30:00 0 2
1 4000 16:30:00 1 3
1 4000 18:30:00 0 4
What I want to do is select SCHEDULE_TIME for the last 2 IDX's where DEV_ID is 3000, so I would like to save 18:30:00 and 20:30:00 in a variables, some examples of statements Ive tried are:
select SCHEDULE_TIME from ARRAY_BAC_SCH_Schedule order by IDX desc limit 1 where DEV_ID = 3000
select SCHEDULE_TIME from ARRAY_BAC_SCH_Schedule order by IDX desc limit (1,1) where DEV_ID = 3000
SELECT TOP 1 SCHEDULE_TIME FROM ARRAY_BAC_SCH_Schedule WHERE DEV_ID = 3000 ORDER BY IDX DESC
Right now Im just worrying about how to get the select statement to work in Query tool before I implement it in the java side. Thanks, Beef.
For SQL Server you should use
SELECT TOP 2 SCHEDULE_TIME from (select SCHEDULE_TIME FROM ARRAY_BAC_SCH_Schedule WHERE DEV_ID = 3000 ORDER BY IDX DESC) as inner
like Hemal told you.
Be careful with queries like
select TOP 2 SCHEDULE_TIME FROM ARRAY_BAC_SCH_Schedule WHERE DEV_ID = 3000 ORDER BY IDX DESC
because that is wrong. SQL Server does the top and then the order.
In PostgreSQL or MySQL you should use limit and the end of the query. The limit is after the where part.
In Oracle you should use rownum inside the where part.
Maybe I'm missing something. Is there a reason you wouldn't just run:
select SCHEDULE_TIME from ARRAY_BAC_SCH_Schedule order by IDX desc limit 2 where DEV_ID = 3000
This should return 2 rows, containing 20:30:00 and 18:30:00.
if it is mysql then
select SCHEDULE_TIME from ARRAY_BAC_SCH_Schedule where DEV_ID = 3000 order by IDX desc limit 2
I think
SELECT TOP 2 * from (select SCHEDULE_TIME FROM ARRAY_BAC_SCH_Schedule WHERE DEV_ID = 3000 ORDER BY IDX DESC) as inner
The specifics will vary a little based on your DB, but your query should look something like this:
SELECT TOP 2 SCHEDULE_TIME
FROM ARRAY_BAC_SCH_Schedule
WHERE DEV_ID = 3000
ORDER BY IDX Desc
Or, on one line:
SELECT TOP 2 SCHEDULE_TIME FROM ARRAY_BAC_SCH_Schedule WHERE DEV_ID = 3000 ORDER BY IDX Desc
You can do that with subquerys:
select * from array_bac_sch_schedule where (value_enum,idx) in (select value_enum,idx from array_bac_sch_schedule where dev_id=3000) order by schedule_time desc limit 2;
I took value_enum and idx as primary key.