get the nearest highest value from a list oracle sql - sql

I have a column in the database in the following format: yymmddhh24miss
Sample Data:
140203101241
140202101141
140102101240
143001101244
142801101245
142701131347
142601121542
142101131744
...
I need to get the nearest high value from the list. Ex: If I pass 142701131333, then it should return 142701131347 from the above list.
Any help appreciated!

SELECT data
FROM
(
SELECT data
FROM tbl
WHERE data > '142701131333'
ORDER BY data
) a
WHERE rownum = 1

SQL> with t (x) as (
2 select 140203101241 from dual union all
3 select 140202101141 from dual union all
4 select 140102101240 from dual union all
5 select 143001101244 from dual union all
6 select 142801101245 from dual union all
7 select 142701131347 from dual union all
8 select 142601121542 from dual union all
9 select 142101131744 from dual
10 )
11 select min(x) minx from t where x > 142701131333
12 /
MINX
-----------------
142701131347

SELECT MIN(sample_data)
FROM tableName
WHERE sample_data > 142701131333

Related

Is there any alternative to use MYSQL's ADDDATE() in ORACLE?

I have this query that needs to be executed for oracle sql instead of mysql which is where it originally came from, but I have the ADDDATE() function which I don't see any other alternative than DateAdd since it needs more parameters than I really need..
Apart from that, if I try to execute it, it also indicates an error in the
SELECT 0 i UNION.................
part, saying the following ORA-00923: FROM keyword not found where expected
Maybe in oracle it is not allowed to do a select 0 union select 1 union...
Any suggestions or help I appreciate it, thanks
SELECT
ADDDATE('1970-01-01', t4.i * 10000 + t3.i * 1000 + t2.i * 100 + t1.i * 10 + t0.i) selected_date
FROM
(
SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) t0,
(
SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) t1,
(
SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) t2,
(
SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) t3,
(
SELECT 0 i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) t4
In Oracle you must select from the one-row table dual in order to select one row. You cannot select without a from clause.
If you want to generate dates, you'll write a standard SQL recursive CTE. (And this is the typical approach now in MySQL, too, since version 8.0.)
Here is an example selecting all days for 1970:
with dates (dt) as
(
select date '1970-01-01' from dual
union all
select dt + interval '1' day from dates where dt < date '1970-12-31'
)
select dt from dates;
Here is another way to SELECT a list of dates for the year 1970. Adjust the starting and ending dates if you want different years or the INTERVAL if you want different periods like seconds, minutes, hours…
ALTER SESSION SET NLS_DATE_FORMAT = 'DD-MON-YYYY HH24:MI:SS';
with dt (dt, interv) as (
select date '1970-01-01', numtodsinterval(1,'DAY') from dual
union all
select dt.dt + interv, interv from dt
where dt.dt + interv <= date '1970-12-31')
select dt from dt;
/

How to get mean of exams by client with 2 tables?

I know a little bit of sql, only the basic, now I need to create a analytic query but can't do this yet.
I have 2 tables on my db oracle, client and exams:
I am tried a lot of ways to get the mean of exams by client, but no success yet.4
The result expected is:
exams = 13
clients = 6
13/6= 2.166666666...7
How can I do that?
If you have clients who have not taken any exams then you want:
SELECT AVG(COUNT(e.nu_ordem)) AS avg_exames_by_client
FROM cliente c
LEFT OUTER JOIN exames e
ON (c.id = e.id_cliente)
GROUP BY c.id;
or:
SELECT (SELECT COUNT(*) FROM exames) / (SELECT COUNT(*) FROM cliente)
AS avg_exames_by_client
FROM DUAL;
Which, for the sample data:
CREATE TABLE cliente (id PRIMARY KEY) AS
SELECT 1 FROM DUAL UNION ALL
SELECT 2 FROM DUAL UNION ALL
SELECT 3 FROM DUAL UNION ALL
SELECT 4 FROM DUAL UNION ALL
SELECT 5 FROM DUAL UNION ALL
SELECT 6 FROM DUAL;
CREATE TABLE exames (nu_ordem PRIMARY KEY, id_cliente) AS
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 2, 5 FROM DUAL UNION ALL
SELECT 3, 5 FROM DUAL UNION ALL
SELECT 4, 2 FROM DUAL UNION ALL
SELECT 5, 6 FROM DUAL UNION ALL
SELECT 6, 1 FROM DUAL UNION ALL
SELECT 7, 1 FROM DUAL UNION ALL
SELECT 8, 4 FROM DUAL UNION ALL
SELECT 9, 5 FROM DUAL UNION ALL
SELECT 10, 3 FROM DUAL UNION ALL
SELECT 11, 6 FROM DUAL UNION ALL
SELECT 12, 2 FROM DUAL UNION ALL
SELECT 13, 1 FROM DUAL;
Both output:
AVG_EXAMES_BY_CLIENT
2.166666666666666667
If you then add a couple of clients but no more exams:
INSERT INTO cliente (id)
SELECT 7 FROM DUAL UNION ALL
SELECT 8 FROM DUAL
Then the average is:
AVG_EXAMES_BY_CLIENT
1.625
db<>fiddle here
You can try below formula to get the result -
SELECT COUNT(*)/COUNT(DISTINCT id_cliente)
FROM exams;

using regular expression that not include string '05613'. have NAW_05613_11_PL04_02 in table. need condition rows which have 05613 not be displayed

I want to fetch data from database using regular expression which should not include string '05613'.
I have values like NAW_05613_11_PL04_02 in my table. I want to give condition that all rows which have 05613 in it should not be displayed.
I have tried using REGEXP_LIKE(d.variable_value_string, '^N(*)[^{05613}](*)')
SELECT * from tablename where REGEXP_LIKE(columnname, '^N(*)[^{05613}](*)')
Expected result should be- row with value having 05613 should not be retrieved.
A simple LIKE could be enough:
... columnName not like '%05613%'
For example:
SQL> with test(c) as (
2 select '05613XX' from dual union all
3 select 'XX05613' from dual union all
4 select 'X05613X' from dual union all
5 select 'XXX' from dual
6 )
7 select *
8 from test
9 where c not like '%05613%';
C
-------
XXX
SQL>
If you need, for some reason, regexp_like, this is a way:
SQL> with test(c) as (
2 select '05613XX' from dual union all
3 select 'XX05613' from dual union all
4 select 'XX05613' from dual union all
5 select 'X05613X' from dual union all
6 select 'XXX' from dual
7 )
8 select *
9 from test
10 where not regexp_like(c, '05613');
C
-------
XXX
If this is your assignment and usage of regexp_like is mandated then use following regexp_like:
SELECT * from tablename D
where Not REGEXP_LIKE(d.variable_value_string, '05613')
Cheers!!

How to upside down the result rows of a select statment in oracle?

I can select a list of rows from a table. but I want to show them by swapping upside down.
Explaination:
with table1 as
(
select 1 ID, 'txt1' value from dual
union all
select 2, 'txt2' from dual
union all
select 7, 'txt7' from dual
union all
select 5, 'txt5' from dual
union all
select 3, 'txt3' from dual
)
select * from table1;
in above query I can obtain following result
ID | VALUE
------------------
1 txt1
2 txt2
7 txt7
5 txt5
3 txt3
but I want to show them as follows
ID | VALUE
------------------
3 txt3
5 txt5
7 txt7
2 txt2
1 txt1
How to do that?
One approach would be to add a computed column to your set of union queries, then order by that column:
WITH table1 AS (
SELECT 1 ID, 'txt1' value, 1 AS position FROM dual
UNION ALL
SELECT 2, 'txt2', 2 FROM dual
UNION ALL
SELECT 7, 'txt7', 3 FROM dual
UNION ALL
SELECT 5, 'txt5', 4 FROM dual
UNION ALL
SELECT 3, 'txt3', 5 FROM dual
)
SELECT *
FROM table1
ORDER BY pos DESC;
Note that there is no internal order to a SQL table in general. Actually, even the current ordering you are observing is not necessarily guaranteed by Oracle. If you expect a certain order in a result set, you need to impose it via a ORDER BY clause.
How's this?
with table1 as
(
select 1 ID, 'txt1' value from dual
union all
select 2, 'txt2' from dual
union all
select 7, 'txt7' from dual
union all
select 5, 'txt5' from dual
union all
select 3, 'txt3' from dual
)
select * from table1 order by rownum desc;
Actually this is not working for this perticular example. but it is working for normal table.

Select values is a row as column values

How can I retrieve values in a row as column values?
Example:
Consider the output of below query as INPUT :
Select 1,2,3,4,5,6,7,8,9,10
from dual;
I need a query that can give below output:
COL1
----
1
2
3
4
5
6
7
8
9
10
SELECT 1 AS "COL1" FROM dual
UNION
SELECT 2 FROM dual
UNION
SELECT 3 FROM dual
UNION
SELECT 4 FROM dual
UNION
SELECT 5 FROM dual
UNION
SELECT 6 FROM dual
UNION
SELECT 7 FROM dual
UNION
SELECT 8 FROM dual
UNION
SELECT 9 FROM dual
UNION
SELECT 10 FROM dual ;
If you want to generate a sequence of numbers in Oracle:
with n as (
select level as n
from dual
connect by level <= 10
)
select *
from n;
Or, if you have 10 columns, you can do an unpivot. An easy way is with union all:
select col1 from t union all
select col2 from t union al
. . .
select col10 from t;