Using subquery with IN clause - sql

I am stuck at one particular problem here, I am fetching ID's from one column that are like this ',90132988,90133148,72964884,' Let's say this value is stored in a column ColumnA of Table1.
I want to use this in another query that's using IN clause something like this.
SELECT *
FROM USER_GROUP
WHERE ID IN (SELECT CONCAT(CONCAT('(',REPLACE(LTRIM(RTRIM(REPLACE(COLUMNA, ',', ' '))), ' ', ',')),')') FROM Table1)
When I run this query I get invalid number error. Any suggestions ?

You get a number error because id is a number. So, Oracle wisely assumes that the subquery returns numbers.
I think the logic you want is:
SELECT ug.*
FROM USER_GROUP ug
WHERE EXISTS (SELECT 1
FROM Table1 t1
WHERE t1.COLUMNA LIKE '%,' || ug.ID || ',%'
);
I strongly discourage you from storing number lists as strings. Just store one row per number. That is really much simpler and the resulting code will be more efficient.

You can try converting "ID" using TO_CHAR, but you will lose the use of any index on ID if you have one.
SELECT *
FROM USER_GROUP
WHERE TO_CHAR(ID) IN (SELECT CONCAT(CONCAT('(',REPLACE(LTRIM(RTRIM(REPLACE(COLUMNA, ',', ' '))), ' ', ',')),')') FROM Table1)

Related

PostgreSQL: Joining Tables Based on Searched Concatenated Strings

I'm not sure how to write a join clause that takes a value from table 1, then searches a string in table 2 to see if they match. Sound confusing?
Here's the actual example I'm working with.
Table 1
Customer_Id Concat_Phone_Numbers
1 8888888888;1111111111
Table 2
Caller Callee Calldate
1111111111 3333333333 1/1/1900
I want to create a table that looks like this:
Desired Table
Customer_Id Calldate
1 1/1/1900
I'm lost when it comes to writing the join clause so that the entire list in Table 1's second column is searched for a matching phone number/entry.
Thank you in advance for your help! (PS it's my first time asking a question!)
Edit::
Here's where I'm at now
Select
*
from table1
left join table2
on ??????????????????
Yuck! You should fix the data structure. You really need a table with one row per customer and per phone number. You'll understand why if you care about performance.
But, if you are stuck with this data model, you can do a join using string and/or array operations. Here is a method using regular expressions
select . . .
from table1 t1 left join
table2 t2
on t2.caller ~ '^' || replace(t1.phone_numbers, ';', '|') || '$' or
t2.callee ~ '^' || replace(t1.phone_numbers, ';', '|') || '$' ;

Oracle 11g Concat function error

I'm encountering this error:
ORA-00904: "LASTNAME": invalid identifier
When trying to make a report using concat function.
Here is the query:
SELECT 'Full Name','User Name', 'Email' FROM Dual
UNION ALL
SELECT distinct concat(concat(firstname, ' '), lastname), username, Email
FROM
(
select distinct concat(concat(firstname, ' '), lastname), username, Email
from sas_aclentry, sas_usergroup
where sas_aclentry.userkey = sas_usergroup.userkey
and objecttype in (16,3,4,101,14,102) and productkey = 1 and type = 1 and privilege !=0 and isdeleted = 0 and STATUS IN (0, 32)
UNION
select distinct concat(concat(firstname, ' '), lastname), username, Email
from sas_objecttree
join sas_usergroup on sas_usergroup.userkey = sas_objecttree.childkey
where isdeleted = 0 and STATUS IN (0, 32)
and parentkey in (
select distinct sas_aclentry.userkey
from sas_aclentry
join sas_usergroup on sas_usergroup.userkey = sas_aclentry.userkey
where objecttype in (16,3,4,101,14,102) and productkey = 1 and type = 2 and privilege !=0 and isdeleted = 0)
)
WHERE UPPER(Email) LIKE '%SAS%';
Wandered on google but could not find any way to make this works.
Please help.
Appreciate any input.
Will
The error seems to be that your outer query tries to select lastname from the derived table, which does not expose any column with that name. I'm guessing you meant to alias the concated column in the derived table and select that.
Try changing the beginning of the query to this:
SELECT 'Full Name','User Name', 'Email' FROM Dual
UNION ALL
SELECT fullname, username, Email
FROM
(
select distinct firstname || ' ' || lastname as fullname, username, Email
With some databases concat can take more than two arguments, I'm not sure this is true for Oracle though, but you should be able to use the concatenation operator || and change your nested concat functions to this:
firstname || ' ' || lastname as fullname
which makes the code a bit cleaner. (I would also try to be consistent in the use of explicit joins - in the derived table you use implicit joins for the first query and explicit for the second).
There are many mistakes in this query, besides what has already been pointed out (you are selecting "lastname" from a subquery whose projection does not contain a column by that name).
When you do a UNION, the first term of the union must have column names or aliases, which will be used for all the terms of the union. It does not suffice to select three strings from dual (which are probably meant to be used as headers), you must also give each of them an alias. For example, select 'Full Name' as fullname, ... from dual. Alternatively, you may leave the select... from dual for later in the union.
The fact that the "column headers" are shown at the top of the query does not mean they will be at the top of the result set. If you want them to show up at the top of your results, you must use an ORDER BY clause (which probably also means you will need to be able to order by something).
In the "problem" part of the Union, the select with a subquery, with the names and concatenations, you concatenate in the subquery, and then in the select list of the outer query you concatenate again (and supposedly the same three columns that the subquery concatenated already). This will not produce the result you wanted even if there were no syntax errors. What you probably want to do is to do the concatenation in the subquery (and best to use the || operator which may be used repeatedly, instead of concat() which is limited in Oracle); alias the result of the concatenation as fullname, and select fullname in the outer query.
After you fix these issues, others may come to the front; I (we) am/are not able to test, since you didn't provide any test inputs. Please follow up / write back if you need more help. Good luck!

Is it possible to have a where with a select statement which you add wildcards to

I have a situation where I need to use a select statement in a where but then also append and prepend wildcards to the value it returns. E.g something like:
select * from [Customers.customervisibility] where userId like '%,' (Select Id from [Users.Users] where name ='MyName') ',%'
but running this gives:
Incorrect syntax near ',%'.
Now the Select Statement is only ever going to return 1 id, so I don't know if there is a better way to write it maybe using a function.
The overall goal is so that I can select the rows from [customer.customervisibility] where the id is contained in a comma seperated string column [UserId]
e.g. if id = 8
I need to get the rows where *,8,*...
It has to be inline, I cannot use variable, and you will have to excuse the TERRIBLE database design. this is so that it will work with third party software
Try this where clause
If your DBMS support Concat the use this.
userId like concat('%' ,(Select top 1 cast(Id as varchar(50)) from [Users.Users] where name ='MyName') ,'%')
Else
userId like '%' +(Select top 1 cast(Id as varchar(50)) from [Users.Users] where name ='MyName') +'%'
I have used Top 1 to avoid sub-query returns more than one row error if in case your subquery returns more than one row
You seem to have forgotten the concatenation character + for strings. Try below query:
select * from [Customers.customervisibility] where userId like '%,'+(Select Id from [Users.Users] where name ='MyName')+',%'
This will give results whose userId contains your Id where userId is a comma separated string.
SELECT *
FROM [Customers.customervisibility]
WHERE (userId LIKE '% , Select Id from [Users.Users] where status="MyName" %')
Try this:
select * from [Customers.customervisibility] where convert(VARCHAR(100),userId) like '%'+(Select Id from [Users.Users] where name ='MyName')+'%'

"NOT IN" subquery with a leading wildcard

I have two tables:
Table tablefoo contains a column fulldata.
Table tablebar contains a column partialdata.
I want find a list of tablefoo.fulldata that do NOT have partial matches in tablebar.partialdata.
The following provides a list of tablefoo.fulldata with partial matches in tablebar, but I want the negative of this.
select fulldata from tablefoo
where fulldata like any (select '%' || partialdata from tablebar);
This lists every record in partialdata:
select fulldata from tablefoow
where partialdata not in (select '%' || partialdata from tablebar);
Any idea how to get only the results tablefoo.fulldata that do not contain matches to a leading wildcarded tablebar.partialdata?
I found this link: PostgreSQL 'NOT IN' and subquery which seems like it's headed down the right path, but I'm not getting it to work with the wildcard.
Sure, I could write a script to pull this out of psql and do the comparisons, but it would be much nicer to handle this all as part of the query.
SELECT fulldata
FROM tablefoo f
WHERE NOT EXISTS (
SELECT 1
FROM tablebar b
WHERE f.fulldata LIKE ('%' || b.partialdata)
);

T-SQL Using CONTAINS predicate with Hyphen

Imagine a table (table1) with one column (column1) and one record whose value is 'roll-over'. Then use the following SQL query and you will not get any records.
select * from table1 where contains(column1, ' "roll-over" ')
Is there a way to escape the hyphen in the search text? So far I have not been successful trying this (I have tried all below escapes with no success).
select * from table1 where contains(column1, ' "roll\-over" ')
select * from table1 where contains(column1, ' "roll!-over" ')
select * from table1 where contains(column1, ' "roll[-]over" ')
Also, please note that using the LIKE keyword is not possible for my application because I am taking advantage of full-text search indexing.
It looks like you may not be able to do that. Give this article a read:
https://support.microsoft.com/en-us/help/200043/prb-dashes---ignored-in-search-with-sql-full-text-and-msidxs-queries
They suggest searching only alphanumeric values (lame) or using the LIKE Clause (not an option for you).
Partial solution: you can force the query to return records containing hyphens (or any character) by using the charindex function to test that the string contains the character, e.g.:
select * from table1 where contains(column1, ' "roll-over" ')
and charindex('-', column1) > 0