Is it possible in SQL to match a LIKE from a list of records in a subquery? - sql

Using these tables, as a sample:
CodeVariations:
CODE
-----------
ABC_012
DEF_024
JKLX048
RegisteredCodes:
CODE AMOUNT
-------- ------
ABCM012 5
ABCK012 25
JKLM048 16
Is it possible to write a query to retrieve all rows in RegisteredCodes when CODE matches a pattern in any row of the CodeVariations table? That is, any row that matches a LIKE pattern of either 'ABC_012', 'DEF_024' or 'JKLX048'
Result should be:
CODE AMOUNT
-------- ------
ABCM012 5
ABCK012 25
I'm using PostgreSQL, but it would be interesting to know if it's possible to do this in a simple query for either PostgreSQL or any other DB.

Does this do what you need?
select distinct RC.* from RegisteredCodes RC, CodeVariations CV
where RC.CODE LIKE CV.CODE;

Is this you are looking for:
SELCET * FROM RegisteredCodes RC WHERE RC.Code IN (SELECT CODE FROM CodeVariations WHERE CODE LIKE ('ABC%') AND CODE LIKE ('%012')
This will fetch all the record that start with 'ABC' and Ends with '012' and similar for 'DEF" and 'JKL'.
OR
Are you looking for something like this?

select * from CAT_ITEM where DESCRICAO LIKE '%TUBO%%PVC%%DNR%'
All like list is in a string.

In Oracle & PostgreSQL you can you single char wildcards "_" for single chars.
select RC.* from RegisteredCodes RC, CodeVariations CV
where RC.CODE LIKE 'ABC_012';
use Substring
select RC.* from RegisteredCodes RC, CodeVariations CV
where RC.CODE LIKE substring(CV.Code,1,3)||'_'||substring(CV.Code,5) ;

Related

Joining results from one query with another query

I have two queries. The first gives me a list of BusinessUnitIds along with a count for each:
SELECT [b].[BusinessUnitId], COUNT([b].[BusinessUnitId]) AS bucount
FROM [dbo].[ComponentTeamBusinessUnit] [b]
WHERE [b].[GlobalClientFiscalYearId] = #GlobalClientFiscalYearId
AND [b].[ComponentTeamId] IN (SELECT items FROM [dbo].[fnSplit](#ComponentTeamIds, ','))
GROUP BY [b].[BusinessUnitId])
I want to take the BusinessUnitIds in this result and join them to a second query which will retrieve the Business Unit Name associated with the BusinessUnitIds. Something like the following:
Select [c].Name, [first query result].Count from [dbo].[BusinessUnit] [c]
INNER JOIN [first query result]
WHERE [c].BusinessUnitId = [first query result].BusinessUnitId
Ultimately, what I want is a listing of Business Names, along with a count of each. I haven't been able to figure out how to do this. Can anyone help? To do both queries in a single statement would be tops. Thank you.
Exmaple:
SELECT [b].[BusinessUnitId],A.Name, COUNT([b].[BusinessUnitId]) AS bucount
FROM [dbo].[ComponentTeamBusinessUnit] [b]
LEFT JOIN NameTable as A
ON A.BusinessUnitId = b.BusinessUnitId
WHERE [b].[GlobalClientFiscalYearId] = #GlobalClientFiscalYearId
AND [b].[ComponentTeamId] IN (SELECT items FROM [dbo].[fnSplit](#ComponentTeamIds, ','))
GROUP BY [b].[BusinessUnitId],A.Name
If tables are One to One, will be neat, if one to many, you will see the result like:
id name count
1 A 5
1 B 6
And if you want to group id 1, to get:
id name count
1 A,B 11
That you need to use FOR XML PATH() together with STUFF, or STRING_SPLIT, really depends on your real case.

compare records within same table

I have Student_Table with following structure.
Student_Note Table
student_id seq_num note
11212 1 firstnote
11212 2 secondNote
11212 3 thirdNote
21232 1 secondstudentnote1
21232 2 secondstudentnote2
so on
I want to get latest note (which has largest seq_num) for a particilar student.
I have tried following query
select tn.note from Student_Note tn JOIN Student_Note tn1
ON (tn.student_id =tn1.student_id AND tn.seq_num < tn1.seq_num)
where tn.student_id=11212
it is giving more than one row. How to achieve aforementioned scenario ?
I forgot mention that I am using above query as subquery . As per sybase TOP clause will not work in subquery.
P.S. I am using sybase.
OK - changed as apparently cannot use TOP.........
select tn.note from Student_Note tn
where tn.student_id=11212
and tn.seq_num = (SELECT MAX(seq_num) from Student_Note WHERE Student_Note.Student_Id = tn.Student_Id)
Please try this
select substring(max(str(seq_num,10,'0') + note),11,len(note))
from Student_Note
where student_id=11212

SQL: Select 2 tables without join

I wrote this SQL query:
SELECT *
FROM
dbo.RDB_LOG_ITEM,
(
SELECT '000' + CAST(operatore as varchar) + cast(scontrino as varchar) search
FROM
(
SELECT
N0_XACT_NO scontrino,
N0_OPERATOR_NO operatore
FROM
dbo.RDB_SCALE_ITEM
WHERE
BL_RECORD_EXPLODED = 0 AND
N0_COUNTER_NO = 1 AND
DT_TIME_STAMP LIKE '20160526%'
) db
) db2
WHERE
DT_TIME_STAMP > '2016-05-26T00:00:00.000' AND
SZ_SCALE_LABEL LIKE db2.search + '%'
But this query is executed in 3+ sec. The result of this query is a single row. The result of the select db2 are only 7 rows.
I think when I use from data1,db2 that SQL does a cross join (data1 is a big db with something like 300k+ rows) and slows the process.
If I try to write the select hard-coded with the result from the 2nd select I get the result in 0.01 sec like this: select * from data1 where DT_TIME_STAMP > '2016-05-26T00:00:00.000' and SZ_SCALE_LABEL like '0001013530%'
How can I use the db2 without joining it with the other db?
edit
the subquery:
(
SELECT '000' + CAST(operatore as varchar) + cast(scontrino as varchar) search
FROM
(
SELECT
N0_XACT_NO scontrino,
N0_OPERATOR_NO operatore
FROM
dbo.RDB_SCALE_ITEM
WHERE
BL_RECORD_EXPLODED = 0 AND
N0_COUNTER_NO = 1 AND
DT_TIME_STAMP LIKE '20160526%'
) db
) db2
give me X rows like
0001013530
0001013531
0001013532
0001013533
0001013534
what i need is a query like this select * from dbo.RDB_LOG_ITEM where DT_TIME_STAMP > '2016-05-26T00:00:00.000' and (SZ_SCALE_LABEL like '0001013530%' or SZ_SCALE_LABEL like '0001013531%' or SZ_SCALE_LABEL like '0001013532%' or SZ_SCALE_LABEL like '0001013533%' or SZ_SCALE_LABEL like '0001013534%')
i think is something near the subquery IN http://www.dofactory.com/sql/subquery but with the LIKE
PS sorry for the incomplete post but i was at work and they was kicking me for close :-)
First, you should be using explicit JOINs. Your WHERE clause should not have more than one table (in this case, considering the subquery as a "table").
Second, there is no need for a subquery here at all. You need to get out of the habit of leaning on subqueries and think in a set-based way when writing SQL.
Finally, use your aliases to prefix all of your columns in a query. It's impossible to tell where some of these columns are coming from without prefixing them.
I believe that this will get you the same results and will ideally be done in a performant way. If it's not, then you will need to post the full table structures (including indexes) as well as the query plans for anyone to be able to help you with performance issues.
SELECT
LI.dt_time_stamp,
LI.sz_scale_label,
<list other columns here, because we **never** use SELECT *>
FROM
dbo.RDB_LOG_ITEM LI
INNER JOIN dbo.RDB_SCALE_ITEM SI ON
SI.bl_record_exploded = 0 AND
SI.no_counter_no = 1 AND
SI.dt_time_stamp LIKE '20160526%' AND -- You should be using date datatypes for your date columns
LI.sz_scale_label LIKE '000' + CAST(operatore AS VARCHAR(20)) + cast(scontrino AS VARCHAR(20)) + '%' -- I guessed on appropriate VARCHAR sizes, which you should have
WHERE
LI.dt_time_stamp > '2016-05-26T00:00:00.000'
How much data does your tables have? If they have huge data, without join your execution time will be more. I had similar experience. Using join reduced my execution time significantly.

find more than one word in same row

Query to generate a list of companies that have “prior to” more than once in their names.
For Example:
Company Name
Ittal PLC (adz ll **prior to** 04/2012) (Z Amp C **prior to** 02/2009)
One simple way is to use like:
where CompanyName like '%prior to%prior to%'
Try this
select *
from Yourtable
where len([Company Name]) - len(replace([Company Name],'prior to','')) > 1
and len([Company Name]) - len(replace([Company Name],'prior to','')) <> len('prior to')
SQL FIDDLE DEMO
I'd probably implement this as a two-step process.
1) Find all records matching prior to.
E.g.
SELECT Company_name FROM COMPANY_TABLE WHERE Company_name LIKE '%prior to%'
2) Iterate through all the records and find only those that have 2 occurrences of the prior to substring (in whatever language you're using).

SQL - Getting Name Starting with a particular letter

I have a query here that doesn't work and having trouble pin pointing my mistake.
Any help would be great.
Thanks
I am trying to retrieve records with a program name starting with 'C' but my query returns zero records.
My PROGRAM table has an entry of a ProgName of Chemistry.
SELECT P.ProgNumber, ProgName, StudID, DateEnrolled
FROM PROGRAM AS P, STUDENT AS S
WHERE P.ProgNo = S.ProgNo
AND ProgName LIKE 'C%';
Use
LIKE "C*"
MSAccess doesn't use % as the wildcard
SELECT
P.ProgNumber, P.ProgName, S.StudID, S.DateEnrolled
FROM
PROGRAM P
JOIN STUDENT S ON S.ProgNo = P.ProgNo
WHERE
P.ProgName LIKE 'C%';
should work... you said you changed it to ='Chemistry', do you get the same result if you use lowercase c in chemistry?
You need to join the different tables like this...Try this...
SELECT P.ProgNumber, P.ProgName, S.StudID, S.DateEnrolled
FROM PROGRAM P
JOIN STUDENT S
ON P.ProgNo = S.ProgNo
WHERE P.ProgName LIKE 'C*'; -- Asterisk because its Access not MS-SQL