T-SQL CONTAINS with search condition from subquery - tsql

I have a table containing search values and wish to use CONTAINS to search another table with those values. The table to search contains email data.
SEARCHTABLE
ID VALUE
1 '*domain1.com'
2 '*domain2.co.uk'
EMAILTABLE
ID SENDER BODY
1 'fred#domain1.com' 'body text of email'
2 'frank#domain1.com' 'body text of email'
3 'bob#domain3.net' 'body text of email'
is there a way to build a query searching the EMAILTABLE with the values in the SEARCHTABLE in a subquery i.e. the equivalent of :
SELECT * FROM EMAILTABLE where CONTAINS (sender, '*domain.com OR *domain2.co.uk'
I'd be grateful for any assistance with this.

Try like this :
SELECT EMAILTABLE.*
FROM EMAILTABLE
INNER JOIN SEARCHTABLE ON EMAILTABLE.SENDER LIKE '%'+REPLACE(SEARCHTABLE.Value,'*','')+'%'

Related

Select query Prisma Client on Postgres view returning 0 rows when it shouldn't

I am having a problem when trying to select rows from a Postgres view filtering by name.
The result from the query should be a company in company_portfolio named 'any company 2'. However, instead of returning the company, it returns nothing. By nothing I mean an empty array of companies instead of an array containing the company with the name 'any company 2'.
I have created a Postgres view that looks something like this:
CREATE OR REPLACE view company_portfolio as
SELECT company.id,
company.name,
...
FROM "Company" company
LEFT JOIN
(SELECT DISTINCT ... FROM
(SELECT DISTINCT ... FROM "Contract") a
GROUP BY 1) as smpLists
ON company.... = smpLists...
I have created a company with the name: 'any company 2'.
I am querying the table with my prisma client like this:
if (params.name) {
filters = `${filters} AND "name" = '${params.name}'`;
}
return this.prisma.$queryRaw(
`
SELECT * FROM "company_portfolio"
WHERE id IS NOT NULL ${filters}
ORDER BY ${orderBy}
LIMIT ${params.limit}
OFFSET ${params.offset}
`
);
So the end query is like this:
SELECT * FROM "company_portfolio"
WHERE id IS NOT NULL AND name = 'any company 2'
ORDER BY name ASC
LIMIT 1
OFFSET 1
It is returning an empty array, so it is not properly selected the company with the name = 'any company 2'.
I have executed a similar query on the database directly and it returns the desired company.
Does anyone spot what could be wrong here?
Solved it.
I was setting an offset = 1 and a limit = 1. This returns the second row from the select query result.
Since there was only 1 record meeting the criteria of the select query, there was not a second record, thus I was seeing an empty array.

Athena-Querying a table with JSON in one column

I have a parquet file with the following format
id = 2a1ed0848022
raw_value:
[{"state":"MO","city":"O Fallon","location_name":"Jackson Hewitt Tax Service","top_category":"Accounting, Tax Preparation, Bookkeeping, and Payroll Services"},
{"state":"IL","city":"Collinsville","location_name":"L E Smith Jewelry","top_category":"Jewelry, Luggage, and Leather Goods Stores"},
{"state":"MO","city":"O Fallon","location_name":"Bagwasi Family Eyecare","top_category":"Health and Personal Care Stores"},
{"state":"MO","city":"O Fallon","location_name":"Rally's Drive-In Restaurants","top_category":"Restaurants and Other Eating Places"},
{"state":"IL","city":"Collinsville","location_name":"BP","top_category":"Gasoline Stations"}
I would like to create a table in Athena on this parquet file and run a query like this
select maid from test12 where state="MD" and city="Baltimore".
How can I search state and city from the second column which has nested JSON.
The key to this is to use UNNEST. I'm assuming that raw_value is typed as array<struct<state:string,city:string,location_name:string,top_category:string>>.
SELECT id
FROM the_table CROSS JOIN UNNEST(raw_value) rv (location)
WHERE location.state = 'MD' AND city = 'Baltimore'
Using UNNEST like this expands each row in the table to one row per element in the array.
If raw_value is a string column, you need to parse it first. You can find an example of this in this answer: https://stackoverflow.com/a/56176204/1109

Cast a PostgreSQL column to stored type

I am creating a viewer for PostgreSQL. My SQL needs to sort on the type that is normal for that column. Take for example:
Table:
CREATE TABLE contacts (id serial primary key, name varchar)
SQL:
SELECT id::text FROM contacts ORDER BY id;
Gives:
1
10
100
2
Ok, so I change the SQL to:
SELECT id::text FROM contacts ORDER BY id::regtype;
Which reults in:
1
2
10
100
Nice! But now I try:
SELECT name::text FROM contacts ORDER BY name::regtype;
Which results in:
invalid type name "my first string"
Google is no help. Any ideas? Thanks
Repeat: the error is not my problem. My problem is that I need to convert each column to text, but order by the normal type for that column.
regtype is a object identifier type and there is no reason to use it when you are not referring to system objects (types in this case).
You should cast the column to integer in the first query:
SELECT id::text
FROM contacts
ORDER BY id::integer;
You can use qualified column names in the order by clause. This will work with any sortable type of column.
SELECT id::text
FROM contacts
ORDER BY contacts.id;
So, I found two ways to accomplish this. The first is the solution #klin provided by querying the table and then constructing my own query based on the data. An untested psycopg2 example:
c = conn.cursor()
c.execute("SELECT * FROM contacts LIMIT 1")
select_sql = "SELECT "
for row in c.description:
if row.name == "my_sort_column":
if row.type_code == 23:
sort_by_sql = row.name + "::integer "
else:
sort_by_sql = row.name + "::text "
c.execute("SELECT * FROM contacts " + sort_by_sql)
A more elegant way would be like this:
SELECT id::text AS _id, name::text AS _name AS n FROM contacts ORDER BY id
This uses aliases so that ORDER BY still picks up the original data. The last option is more readable if nothing else.

PostgreSQL 9.1: Find exact expression in title

I'm looking for a way to search a specific expression - then a part of its - in all documents (and its values associated). The final order should be:
Complete expression (in title or content): using ILIKE and '%expression%'
One of the word (in title or content): using tsquery on tsvector indexes columns
I have two tables:
documents (id [integer], title [character varying], title_search [tsvector])
values (id [integer], content [character varying], content_search [tsvector], id_document [integer])
Here the request I am doing right now:
(SELECT id, title, content, title_search, content_search, ts_rank_cd(title_search, query) AS rank
FROM to_tsquery('lorem&ipsum|(lorem|ipsum)') query, documents
LEFT JOIN "values" ON id_document=id
WHERE (title ILIKE(unaccent('%lorem ipsum%')) OR content ILIKE(unaccent('%lorem ipsum%'))))
UNION (SELECT id, title, content, title_search, content_search, ts_rank_cd(title_search, query) AS rank
FROM to_tsquery('lorem&ipsum|(lorem|ipsum)') query, documents
LEFT JOIN "values" ON id_document=id
WHERE query ## title_search)
UNION (SELECT id, title, content, title_search, content_search, ts_rank_cd(title_search, query) AS rank
FROM to_tsquery('lorem&ipsum|(lorem|ipsum)') query, documents
LEFT JOIN "values" ON id_document=id
WHERE query ## content_search)
ORDER BY rank DESC, title ASC
By doing this, I can get all documents with this expression and/or a part of its but I can't get to have those correctly ordrered. This is because I am relying on ranking with ts_rank on tsvector field which cannot be used to define exact expression.
So my questions are how I can get this to work as I expect? Am I wrong for using full text search?
Thank you.
It's a bit awkward but a solution I've used before is to include an extra "rank" column in your individual subqueries. For instance, the fist query would look like
select 1 as which_rank, id, title, ...
....
where title ILIKE(unaccent('%lorem ipsum%'))
OR content ILIKE(unaccent('%lorem ipsum%')))
then the second would be
select 2 as which_rank, id, title, ...
...
where query ## title_search
and the third would be
select 3 as which_rank, id, title, ...
...
where query ## content_search
If you include that ranking value in your sort order:
ORDER BY which_rank asc, rank DESC, title ASC
you can make sure the first case gets listed first, the second second, and the third third. You can also re-arrange which is 1, 2, 3 depending on your needs.

SSRS - Refine WHERE Criteria in T-SQL Query

I am developing a report that should return results depending on user-specified parameters. There are 3 report parameters, one is a drop down with 'Locations', and the other two are text parameters to search within 'user_id' and users' first or last name. This is what I am currently using:
SELECT *
FROM UserTable1
WHERE Location = #Location
AND (user_id LIKE '%'+#SearchUserID+'%'
AND first_name LIKE '%'+#SearchUserName+'%'
OR last_name LIKE '%'+#SearchUserName+'%')
If the #SearchUserID parameter field is left blank by the user, all user_ids should be returned (that meet the other 2 parameters). If specified, it will return user_ids that have that substring in the user_id. Same thing goes for the #SearchUserName parameter field. If left blank, it should return all users that meet the other parameters. If specified, it should return all users that have that substring in their first_name or last_name (but only results that meet the other parameters). If both are left blank, it should return all users.
The query I have above is not working. It seems to just return results meeting the #SearchUserName parameter, but disregards the #SearchUserID parameter. Is there a way to fix this? I had put the #SearchUserID filter on the tablix itself, using the expression:
="" & Parameters!SearchUserID.Value & ""
But this has resulted in severely hampered performance..
Try this. You must pass NULL if parameter is blank(empty).
SELECT *
FROM UserTable1
WHERE Location = #Location
AND (user_id LIKE '%'+#SearchUserID+'%'
OR #SearchUserID IS NULL
)
AND (first_name LIKE '%'+#SearchUserName+'%'
OR last_name LIKE '%'+#SearchUserName+'%'
OR #SearchUserName IS NULL
)
"....but disregards the #SearchUserID parameter." What data type of user_id?