sql like command - sql

Using Like operator, how to retrieve a name which is having exact 100 characters
note: I don't want to use 100 underscores _
ex:
select ename from emp where ename like '_____________';
it should not like above
is there any other way

For exactly 100 characters , do
select ename from emp where LEN(ename)=100
For greater than equal to 100 characters
select ename from emp where LEN(ename) >= 100

Many dbms products support the REPEAT function (not ANSI however...)
select ename from emp where ename like repeat('_',100)
Or use CHAR_LENGTH:
select ename from emp where CHAR_LENGTH(ename) = 100

I'm not quite sure what DBMS you using, this is should work under mysql :
select ename from emp where ename like concat('%', REPEAT('_',100),'%');
Above condition is where string have 100 UNDERSCORE whether in beginning, middle or end of string. For condition where string exactly have 100 UNDERSCORE :
select ename from emp where ename = REPEAT('_',100);

select ename from emp where LEN(ename)=100 and ename like '%_%';
LEN is used for length of value and % before and after character means any string which contains atleast one _
for more that ore equal to 100
select ename from emp where LEN(ename)>=100 and ename like '%_%';

You can use following:
WHERE column_name REGEXP [a-z0-9]{100}

Related

Multiple input value for single field - PLSQL

I have created a query in PLSQL to search customer records from the tables. But still has some limitations. In the &CUSTOMER_ID Search field If I Put IN% OR DL100056* It will search All the details which start with IN or giving the exact DL details as output. I want to search multiple values like in the customer Id field I wanna search DL100056,DL1000365,DL1000652 likewise. But my current query not giving multiple outputs.
SELECT
DISTINCT CUSINFO.CUSTOMER_ID AS DEALER_CODE,
CUSINFO.name AS DEALER_NAME,
CUSINFO.CORPORATE_FORM AS FORM_OF_BUSINESS,
C.corporate_form_desc AS FORM_OF_BUSINESS_DESCRIPTION,
ifsapp.Customer_Info_Address_Api.Get_Address1(CUSINFO.customer_id,1) "ADDRESS 1",
ifsapp.Customer_Info_Address_Api.Get_Address2(CUSINFO.customer_id,1) "ADDRESS 2",
CREDTIN.credit_limit AS CREDIT_LIMIT,
CREDTIN.allowed_due_amount AS ALLOWED_DUE_AMOUNT,
CREDTIN.allowed_due_days AS ALLOWED_DUE_DAYS,
ORDERC.salesman_code AS SALESMAN_CODE,
BDA.name AS SALESMAN_NAME,
ORDERC.discount AS DISCOUNT,
(select LISTAGG(c.value,' / ') within group (order by c.value) from ifsapp.COMM_METHOD c
where c.method_id_db='PHONE' and c.identity=CUSINFO.customer_id ) "Phone",
(select LISTAGG(c.value,' / ') within group (order by c.value) from ifsapp.COMM_METHOD c
where c.method_id_db='MOBILE' and c.identity=CUSINFO.customer_id) "Mobile",
(select LISTAGG(c.value,' / ') within group (order by c.value) from ifsapp.COMM_METHOD c
where c.method_id_db='FAX' and c.identity=CUSINFO.customer_id) "Fax",
CUSINFO.identifier_reference as IDENTIFIER_REFERENCE
FROM
ifsapp.CUSTOMER_INFO CUSINFO
LEFT JOIN
ifsapp.CUSTOMER_INFO_ADDRESS CUSADD ON CUSINFO.customer_id=CUSADD.customer_id
LEFT JOIN
ifsapp.CUSTOMER_INFO_CONTACT CUSCONT ON CUSINFO.customer_id=CUSCONT.customer_id
LEFT JOIN
ifsapp.CUSTOMER_CREDIT_INFO_CUST CREDTIN ON CUSINFO.customer_id=CREDTIN.identity
LEFT JOIN
ifsapp.CUST_ORD_CUSTOMER_ENT ORDERC ON CUSINFO.customer_id=ORDERC.customer_id
LEFT JOIN
ifsapp.Comm_Method COMM ON CUSINFO.customer_id=COMM.customer_id
LEFT JOIN
ifsapp.CORPORATE_FORM C ON CUSINFO.corporate_form=C.CORPORATE_FORM
LEFT JOIN
ifsapp.SALES_PART_SALESMAN_LOV BDA ON ORDERC.salesman_code=BDA.salesman_code
WHERE CUSINFO.CUSTOMER_ID LIKE '&CUSTOMER_ID'
It can't work that way; one option is to use such a query (I don't have your tables so I used Scott's DEPT): it splits parameter values (separated by comma) into rows and uses them as a subquery. So, what you need is lines #3 - 5 (adjusted to your table / column name).
SQL> select deptno, dname, loc
2 from dept
3 where deptno in (select to_number(regexp_substr('&&par_deptno', '[^,]+', 1, level))
4 from dual
5 connect by level <= regexp_count('&&par_deptno', ',') + 1
6 )
7 order by deptno;
Enter value for par_deptno: 10
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
SQL> undefine par_deptno
SQL> /
Enter value for par_deptno: 20,40
DEPTNO DNAME LOC
---------- -------------- -------------
20 RESEARCH DALLAS
40 OPERATIONS BOSTON
SQL>
please format your sql better, it is very difficult to understand the logic behind the query if its is unreadable.
You could try by using LIKE 'DL%'. This will look for all strings starting with DL. Another solution, if the code doesn't always start with 'DL', is using a substring on the code to get the first few characters, then adding '%'
hope this helped

Multiple where statement returning undesired result

I'm trying to retrieve employees within depts 10 and 30 with a salary greater than 1500. This is the statement I'm running.
select ename, sal
from emp
where deptno = 10
or deptno = 30
and sal > 1500;
It returns:
Name Salary
---------- --------------
NAME1 1600
NAME2 2850
NAME3 2450
NAME4 5000
NAME5 1300
When I run the query without the OR for only one dept, it returns NAME1 and NAME2, when I run it for the other dept it returns NAME3 and NAME4.
My question is, is it the OR statement that's giving me the incorrect NAME5? To me that query should work, I tried using AND instead of OR and it gives me no results. Any help would be appreciated.
AND has precedence over OR in a SQL WHERE clause, so what you have is equivalent to
where deptno = 10 or (deptno = 30 and sal > 1500)
Try putting parentheses around the OR to see if it gives you the results you expect.
where (deptno = 10 or deptno = 30) and sal > 1500
(Also, it would clarify things a little bit if you included the department number in your SELECT so you can see which department each row is coming from.)
Your problem is the lack of parentheses. But really the best way to write the query uses in:
select ename, sal
from emp
where deptno in (10, 30) and
sal > 1500;

Joining two tables and returning the bigger value of one column

Recently I came up with the scenario where I have two tables named emp1 and emp2 and it has following columns and table looks like below
table: emp1
dno sal
10 1000
20 2000
30 3000
table: emp 2
dno sal
10 4000
20 5000
30
and the output table is like
table: output
dno sal
10 4000
20 5000
30 3000
You need to join the two tables, then use the greatest() function to return the bigger of the two values.
As the salary can be null you need to take that into account using the coalesce() function:
select t1.dno, greatest(coalesce(t1.sal,0), coalesce(t2.sal,0)) as sal
from emp1 t1
join emp2 t2 on t1.dno = t2.dno;
SQLFiddle example: http://sqlfiddle.com/#!15/bca1b/1
According to your comment, i think this is what you want:
select e1.dno,
case when nvl(e1.sal,0) > nvl(e2.sal,0) then nvl(e1.sal,0) else nvl(e1.sal,0) end as sal
from emp1 e1
inner join emp2 e2
on e1.dno = e2.dno
This is for oracle. For mysql, mssql, use isnull() instead of nvl()
I think you want to use the results from table2 - but if there is a Null-value in table2 you want to use table1?
SELECT table1.dno, NVL(table1.sal, table2.sal)
FROM table1, table2
WHERE table1.dno = table2.dno(+)

How to suppress null with single row

I have a oracle table like
Name Sal Bonus
ABC 400 null
ABC null 5
How to make it single row and remove null data
Name Sal Bonus
ABC 400 5
Please suggest. Using oracle sql.
If you have just two rows, you can use group by clause. And sum values inside select statement.
SELECT T.NAME,SUM(NVL(T.SAL,0))AS Sal,SUM(NVL(T.SAL,0)) AS Bonus
FROM TABLE t
GROUP BY T.NAME
Here the result:
Name Sal Bonus
ABC 400 5
select name, max(sal), max(bonus)
from Table
group by name

Using 'case expression column' in where clause

SELECT ename
, job
, CASE deptno
WHEN 10
THEN 'ACCOUNTS'
WHEN 20
THEN 'SALES'
ELSE 'UNKNOWN'
END AS department
FROM emp /* !!! */
WHERE department = 'SALES'
This fails:
ORA-00904: "%s: invalid identifier"
Is there a way to overcome this limitation in Oracle 10.2 SQL ?
How to use the 'case expression column' in where clause ?
The reason for this error is that SQL SELECT statements are logically * processed in the following order:
FROM: selection of one table or many JOINed ones and all rows combinations that match the ON conditions.
WHERE: conditions are evaluated and rows that do not match are removed.
GROUP BY: rows are grouped (and every group collapses to one row)
HAVING: conditions are evaluated and rows that do not match are removed.
SELECT: list of columns is evaluated.
DISTINCT: duplicate rows are removed (if it's a SELECT DISTINCT statement)
UNION, EXCEPT, INTERSECT: the action of that operand is taken upon the rows of sub-SELECT statements. For example, if it's a UNION, all rows are gathered (and duplicates eliminated unless it's a UNION ALL) after all sub-SELECT statements are evaluated. Accordingly for the EXCEPT or INTERSECT cases.
ORDER BY: rows are ordered.
Therefore, you can't use in WHERE clause, something that hasn't been populated or calculated yet. See also this question: oracle-sql-clause-evaluation-order
* logically processed: Note that database engines may as well choose another order of evaluation for a query (and that's what they usually do!) The only restriction is that the results should be the same as if the above order was used.
Solution is to enclose the query in another one:
SELECT *
FROM
( SELECT ename
, job
, CASE deptno
WHEN 10 THEN 'ACCOUNTS'
WHEN 20 THEN 'SALES'
ELSE 'UNKNOWN'
END AS department
FROM emp
) tmp
WHERE department = 'SALES' ;
or to duplicate the calculation in the WHERE condition:
SELECT ename
, job
, CASE deptno
WHEN 10 THEN 'ACCOUNTS'
WHEN 20 THEN 'SALES'
ELSE 'UNKNOWN'
END AS department
FROM emp
WHERE
CASE deptno
WHEN 10 THEN 'ACCOUNTS'
WHEN 20 THEN 'SALES'
ELSE 'UNKNOWN'
END = 'SALES' ;
I guess this is a simplified version of your query or you could use:
SELECT ename
, job
, 'SALES' AS department
FROM emp
WHERE deptno = 20 ;
Your table does not contain a column "department" and thus you can not reference it in your where clause. Use deptno instead.
SELECT ename
, job
, CASE deptno
WHEN 10
THEN 'ACCOUNTS'
WHEN 20
THEN 'SALES'
ELSE 'UNKNOWN'
END AS department
FROM emp /* !!! */ where deptno = 20;
This work for me :
SELECT ename, job
FROM emp
WHERE CASE WHEN deptno = 10 THEN 'ACCOUNTS'
WHEN deptno = 20 THEN 'SALES'
ELSE 'UNKNOWN'
END
= 'SALES'
select emp_.*
from (SELECT ename
, job
, CASE deptno
WHEN 10
THEN 'ACCOUNTS'
WHEN 20
THEN 'SALES'
ELSE 'UNKNOWN'
END AS department
FROM emp /* !!! */ ) emp_ where emp_.department='UNKNOWN';
try:
SQL> SELECT ename
2 , job
3 , CASE
4 WHEN deptno = 10
5 THEN 'ACCOUNTS'
6 WHEN deptno = 20
7 THEN 'SALES'
12 ELSE 'UNKNOWN'
13 END AS department
14 FROM emp /* !!! */ where department = 'SALES';
Oracle tries to filter the number of records to be scanned from table by going for the where clause first before select that is why your query fails. Moreover, your query would have never returned rows with department - "Accounts or Unknown" because of the filter Department="SALES"
Try below instead, that will be easy to be fetched by Engine :
SELECT ename, job,'SALES' AS department
FROM emp
WHERE deptno = 20;