Flexible search Query for stringset? - mysql

Please find the below query:
Table Name : B
query : select * from {B}
ID comp
1 d,e,f
I want to check if the value 'f' is present in comp, or not, using an SQL/Flexible search Query.
Is it possible to write a sql query for this scenario?
Update :
SELECT DISTINCT {b:pk} FROM {A AS a left join B as B on {a:ncode} = {b:ncode} and {a:qCode} = {b:qCode}}
WHERE
{a:compID} IN ()
Assume a:compID is "f"
What should be my subquery after the IN operator to achieve my requirement?

SELECT * FROM {B} where {comp} LIKE '%,f,%'

You can search in string in mysql:
//full search:
SELECT * FROM A WHERE comp LIKE '%f%'
// start with f
SELECT * FROM A WHERE comp LIKE '%f'
// end with f
SELECT * FROM A WHERE comp LIKE 'f%'

This will work:
SELECT FIND_IN_SET('f',(SELECT comp FROM t));
Run this code on Fiddle
If you want to check present or not present then:
SELECT case when FIND_IN_SET('f',(SELECT comp FROM t))=0 then'not present'
else 'present' end from dual;

Start with f
LIKE 'f%'
End with f
LIKE '%f'

Related

"Subquery must return only one column" error in postgresql

I have got an error "ERROR: subquery must return only one column " when I am runing this query:
INSERT INTO details (id, object_id, detail)
(
SELECT
CASE
WHEN (SELECT * FROM details WHERE NOT EXISTS(SELECT 1 FROM main_base WHERE main_base.id = details.id))
THEN
concat(SUBSTRING(main_base.id, '(\d+.\d+.)'), n.counted :: TEXT, 'A')
ELSE
concat( SUBSTRING (main_base.id, '(\d+.\d+.)'), n.counted :: TEXT)
END AS id,
main_base.object_id,
main_base.details
FROM main_base
CROSS JOIN LATERAL
generate_series(1, COALESCE ((string_to_array(main_base.id, '-')) [2] :: INT, 1)) AS n (counted)
WHERE main_base.id LIKE '%-%' AND NOT main_base.details ~ '^\.\d+|\(\.\d+\)'
);
I have not clue what is wrong. I've read some topic that people had the same problem but still dont know how to fix it.
I think the problem is that:
SELECT * FROM details WHERE NOT EXISTS(SELECT 1 FROM main_base WHERE main_base.id = details.id)
Can return more than one row, so causes problems in the WHEN statement. It can return more than one row, as the subquery will return 1 every time the condition is met.
If you want to trigger the case statement based on when there exists some records in this set, could you use:
(SELECT COUNT(*) FROM details WHERE NOT EXISTS(SELECT 1 FROM main_base WHERE main_base.id = details.id)) > 1

Select query in mysql using COALESCE

I want to write a select statement that should filter data based on wildcard characters. I have written something like this but it doesn't serve my purpose:
Select r.CompanyID,r.Description,c.BusinessUnitID,c.BusinessSourceID as BusinessSrcID,
c.Description as BusinessDesc from RCompanyTable r
join CBusinessUnitTable c on r.CompanyID=c.CompanyID
WHERE r.CompanyID like CASE WHEN COALESCE('Regexp(*)', '') = '' THEN r.CompanyID ELSE 'Company2' END
But in this it always executes the else part.
What i am looking for is it should give me all data when i pass * to the condition.
Since in my RCompanyTable i have two records Company1 and Company2, I want that if i pass * in that query then it should return me both company1 and company2 data but if i pass regexp(any1) it should provide me Comapany1 Data and if both conditions are not true then it should go to else part displaying Company2 data
Looking forward to your answer.
Thanks in advance
I don't know exactly what you want with * and regexp(any1), but assuming that they are constant strings, then this query should work:
SET #parameter = '';
Select r.CompanyID
, r.Description
, c.BusinessUnitID
, c.BusinessSourceID AS BusinessSrcID
, c.Description AS BusinessDesc
FROM RCompanyTable r
JOIN CBusinessUnitTable c ON r.CompanyID = c.CompanyID
WHERE (#parameter LIKE '%*%' AND r.CompanyID IN ('Company1', 'Company2'))
OR (#parameter LIKE 'regexp(any1)' AND r.CompanyID = 'Company1')
OR (#parameter NOT IN ('%*%', 'regexp(any1)') AND r.CompanyID = 'Company2')
The #parameter is what you are going to pass in the query.
WHERE r.CompanyID = CASE WHEN r.CompanyId LIKE '%*%' THEN r.CompanyID ELSE 'Company2' END
This where clause returns all records where companyID has a * in it, or the companyID is Company2. Is this what you are after?

How do you use "WHERE x IN y" clauses with clojure/java.jdbc?

I am trying to get a simple DB query working, but I can't get clojure/java.jdbc to select from an IN clause.
The code looks like this:
(sql/with-connection db
(sql/with-query-results rows
["select f.name name
, f.id file_id
from FileCategory fc
join File f
on fc.file = f.id
where fc.category in ?
having count(1) >= ?"
[1 2] ; This is the bit which does not work.
; I have tried (to-array) and (set) too
2]
(into [] rows)))
Any Ideas as to how I may pass the set to the query?
Running the query directly under mysql I get no problems:
mysql> select f.name, f.id from FileCategory fc join File f on fc.file = f.id where fc.category in (1, 2) having count(1) >= 2;
+-----------+----+
| name | id |
+-----------+----+
| some name | 1 |
+-----------+----+
1 row in set (0.02 sec)
mysql>
In case it makes a difference I'm using: org.clojure/clojure 1.4.0, org.clojure/java.jdbc 0.2.3 and mysql/mysql-connector-java 5.1.6.
Try this:
(sql/with-connection db
(sql/with-query-results rows
["select f.name name
, f.id file_id
from FileCategory fc
join File f
on fc.file = f.id
where fc.category in (?, ?)
having count(1) >= ?"
1 2 2]
(into [] rows)))
If you use SQL you must generate a SQL query with the correct number of '?' unfortunately.
You may find that working at a higher level of abstraction works better. eg. your query in korma looks like this:
(defentity file)
(defentity filecategory)
(def categories ["movie" "tv" "news"])
(as-sql (select file
(fields :name :file_id)
(join filecategory (= :file.id :filecategory.file))
(where { :filecategory.category [in categories]} )
(having (> (sqlfn :count 1) 1))))
; SELECT `file`.`name`, `file`.`file_id` FROM `file` LEFT JOIN
; `filecategory` ON `file`.`id` = `filecategory`.`file`
; WHERE (`filecategory`.`category` IN (?, ?, ?))
; HAVING COUNT(?) > ? :: [tv movie news 1 1]
You can tidy this up further by moving the FK declarations into the defentity calls if desired.

Where 'foo' OR 'bar' AND 'lol' OR 'rofl' MySQL

In what order would this be evaluated. My intension is that if it finds either foo or bar, it would also search for lol and rofl.
Is this totally in the woods? And if so, how would one evaluate an expression like that.
The AND operator has higher precedence than OR in MySql, so your current expression evaluates as:
WHERE 'foo' OR ('bar' AND 'lol') OR 'rofl'
Add parentheses to the expression if you want to force the evaluation order:
WHERE ('foo' OR 'bar') AND ('lol' OR 'rofl')
AND will be processed first, after that OR will be processed. So, it will be:
'foo' OR ('bar' AND 'lol') OR 'rofl'
After that, it is left to right order.
take a look at the documentation - AND has a higher precedence, so it would be like this:
WHERE 'foo' OR ( 'bar' AND 'lol' ) OR 'rofl'
SELECT
Id, Name
FROM
TestTable
WHERE
(Name = 'foo') OR (Name = 'bar') AND (Name = 'lol') OR (Name = 'rofl')
Will give you the following result in MS SQL Server:
1 foo
4 rofl
So it seems it will combine bar AND lol and evals foo and rofl seperately like this:
SELECT
Id, Name
FROM
TestTable
WHERE
(Name = 'foo') OR ((Name = 'bar') AND (Name = 'lol')) OR (Name = 'rofl')
What you probably want to do is (technically):
SELECT
Id, Name
FROM
TestTable
WHERE
((Name = 'foo') OR (Name = 'bar')) AND ((Name = 'lol') OR (Name = 'rofl'))

Sql statment where in doesn't work

select TO_CHAR(TRUNC(SYSDATE),'DD MONTH,YYYY'),a.appl_no,a.assigned_to,c.trading_name co_name, ' ' co_name2, d.bank_acct_no credit_acct_no, d.bank_no credit_bank_no, d.bank_branch_no credit_branch_no,a.service_id
from newappl a, newappl_hq b, newappl_ret c, newappl_ret_bank d where a.appl_no = c.appl_no and c.ret_id= d.ret_id and a.appl_no=(select appl_no from newappl where appl_no='224') and c.outlet_no in ('1','2') and rownum=1
Why the out put for above statment is only one row while I have 1 & 2 for following statement
select c.outlet_no from newappl_ret c where appl_no = '224'
its hard to say when you dont see data stored in db but try this one:
select c.outlet_no from mss_t_newappl_ret c where appl_no = 224
check if in the column appl_no there isnt any spacebar
maybe this?
and a.appl_no IN (select appl_no from newappl where appl_no='224')
or delete this expression
and rownum=1