check multiple condition with like statement - oracle

I check two columns if the string "done" or "completed" is available in either of these columns.at this moment I write
case when col1 like '%done%'
or col1 like "%completed%'
or col2 like "%done%'
or col2 like "%completed%'
end as status
this is a sample so it's only 4 lines however if there are multiple strings that need to check it takes a lot of effort to write code like this. Can we write which gives a similar result?
(col1||"-"||col2) like (%done%,%completed%)
i know above code is not possible, but do we have any alternative?

If you have a lengthy list, create a table with one column and insert a row for each key word. Then write your query to join to this table using the LIKE operator:
SELECT DISTINCT m.*
FROM maintable m,
keyword_table k
WHERE m.col1 LIKE '%'||k.keyword||'%'
Just be aware that this will not perform well in bulk (millions of rows). That would require more advanced techniques, but for small tables this is fine.

Related

How to make a dynamic select based on a result set from previous step on Pentaho Kettle?

I want to execute a select statement based on a result set from a previous step, something like this:
select column from table where column in (previous step);
Basically this step (filter rows) will split a group of ids based on a condition. I want to make a select with those who tested false but i don't know how to select only those. The table in question, which I want to select, it's very big and it is very expensive to select all records and join with the result set, so I wish to select just the group that I need, is this even possible ?
https://i.stack.imgur.com/Xu1qt.png
Ok, let me try to be more specific.
Basically I Have 3 steps as my print shows.
First step is a table input, which I select from a table.
Second step is a database lookup, which I look on other table to get some fields that I want.
And third step it's a filter rows, where I kinda make a if else statement.
After my third step (filter rows) I have 2 streams: True or False.
Each stream returns me a group of ids and other fields too but it's not that important here, I guess.
I want to make a select statement based on those ids returned from previous step (Filter rows 3° step).
Basically the behaviour that I want its similar to this query:
select *
from table
where id in ("previous step");
Where table will always be the same table, so I don't think this will be a problem or something.
And "previous step" means all ids returned after the 3° step (filter rows).
What i am doing right now is: I have another table input on the other side which I make a merge join with this result set(from 3° step). But I have to make a select of the entire table and then, join with my result set, what is very expensive, and I'm wondering if i can get the same result, but with more performance.
I don't know if I am being clear enough, but I apologize right now because english it's not my main language, but I hope you guys can understand me now, thanks.
You can use three steps to achive this.
First, use a Memory group by step to group ids as a field.The aggregate tyoe should beConcatenate strings separated by ,
Second,use a User defined java expression step to generate a new field contains the SQL we need.The expression may like"SELECT id,created FROM test WHERE order_id IN ("+ ids +")" and ids is the group result from last step.
At last,we can use a Dynamic SQL row step to look up datas by the specified SQL.

Full outer joins or Union . which is faster ( My table has a million rows )

I have to join 3 tables to retrieve data and looks like full outer join is a potential solution but during my try it took more than a hour to execute the query .
Any alternatives would be helpful .
thank you.
Not sure what your query looks like however, add indexes on the table if these tables are newly being created.
However, answering your question using UNION ALL will be faster, as it simply passes the first SELECT statement, and then parses the second SELECT statement and adds the results to the end of the output table. Even a Normal UNION is faster than a join.
The UNION's will make better use of indexes which could result in a faster query.

Oracle - select statement alias one column and wildcard to get all remaining columns

New to SQL. Pardon me if this question is a basic one. Is there a way for me to do this below
SELECT COLUMN1 as CUSTOM_NAME, <wildcard for remaining columns as is> from TABLE;
I only want COLUMN1 appear once in the final result
There is no way to make that kind of dynamic SELECT list with regular SQL*.
This is a good thing. Programming gets more difficult the more dynamic it is. Even the simple * syntax, while useful in many contexts, causes problems in production code. The Oracle SQL grammar is already more complicated than most traditional programming languages, adding a little meta language to describe what the queries return could be a nightmare.
*Well, you could create something using Oracle data cartridge, or DBMS_XMLGEN, or a trick with the PIVOT clause. But each of those solutions would be incredibly complicated and certainly not as simple as just typing the columns.
This is about as close as you will get.
It is very handy for putting the important columns up front,
while being able to scroll to the others if needed. COLUMN1 will end up being there twice.
SELECT COLUMN1 as CUSTOM_NAME,
aliasName.*
FROM TABLE aliasName;
In case you have many columns it might be worth to generate a full column list automatically instead of relying on the * selector.
So a two step approach would be to generate the column list with custom first N columns and unspecified order of the other columns, then use this generated list in your actual select statement.
-- select comma separated column names from table with the first columns being in specified order
select
LISTAGG(column_name, ', ') WITHIN GROUP (
ORDER BY decode(column_name,
'FIRST_COLUMN_NAME', 1,
'SECOND_COLUMN_NAME', 2) asc) "Columns"
from user_tab_columns
where table_name = 'TABLE_NAME';
Replace TABLE_NAME, FIRST_COLUMN_NAME and SECOND_COLUMN_NAME by your actual names, adjust the list of explicit columns as needed.
Then execute the query and use the result, which should look like
FIRST_COLUMN_NAME, SECOND_COLUMN_NAME, OTHER_COLUMN_NAMES
Ofcourse this is overhead for 5-ish columns, but if you ever run into a company database with 3 digit number of columns, this can be interesting.

MS SQL statement using PARTIAL and DISTINCT in VB.NET

I have a table called Postcodes which has over half a million records.
Inside this table i have a column called PostCodeText which has the following:
NG1 1AA
NG1 1AB
NG1 1AC
NG2 1AA
NG2 5TH
NG17 3LP
DE15 4BP
NG17 5GL
DE19 4EE...
What I need is a MSSQL statement that return DISTINCT matches based on a partial string. For example: If I wanted to find all distinct NG postcodes I would want to return:
NG1
NG2
NG17
I've tried something like:
SELECT DISTINCT postcodetext
FROM postcodes
WHERE (postcode_text LIKE 'NG%')
ORDER BY postcodetext
I feel I might be close to the answer but its not there yet, any help would be much appricated.
Also I heard that using LIKE is a slower option then using = is there a faster way then doing this?
Try
SELECT LEFT(postcodetext,CHARINDEX(' ',postcodetext,0))
FROM postcodes
WHERE postcodetext like 'NG%'
GROUP BY LEFT(postcodetext,CHARINDEX(' ',postcodetext,0))
ORDER BY postcodetext
OK, I think I'm missing something here, the above statement work fine (if I drop the ORDER BY), when I run it in management studio. But when I run it in my VB.net code I'm having an issue:
After running the statement and assigning the values into my datatable, I then use the following code :
For Each rows In dt.Rows
Select Case opt
Case 1 '
frmSettings.lstAllPostcodes.Items.Add(rows.Item("postcodetext"))
frmSettings.ProgBarSettings.Value = i
i = i + 1
End Select
Next
It fails when trying to reference rows.item("postcodetext"). I realise that has something to do with the SELECT statement using the LEFT of. I would like my listbox to hold the partial results (ie NG1, NG2, NG17 etc etc)

Stored Procedure: Cursor is bad?

I read somewhere that 99% of time you don't need to use a cursor.
But I can't think of any other way beside using a cursor in this following situation.
Select t.flag
From Dual t;
Let's say this return 4 rows of either 'Y' or 'N'. I want the procedure to trigger something if it finds 'Y'. I usually declare a cursor and loop until %NOTFOUND. Please tell me if there is a better way.
Also, if you have any idea, when is the best time to use a cursor?
EDIT: Instead of inserting the flags, what if I want to do "If 'Y' then trigger something"?
Your case definitely falls into the 99%.
You can easily do the conditional insert using insert into ... select.... It's just a matter or making a select that returns the result that you want to insert.
If you want to insert one record for each 'Y' then use a query with where flag = 'Y'. If you only want to insert a single record depending on whether there are at least one 'Y', then you can add distinct to the query.
A cursor is useful when you make something more complicated. I for example use a cursor when need to insert or update records in one table, and also for each record insert or update one or more records into several other tables.
Something like this:
INSERT INTO TBL_FLAG (col)
SELECT ID FROM Dual where flag = 'Y'
You will usually see a performance gain when using set based instead of procedural operations because most modern DBMS are setup to perform set based operations. You can read more here.
well the example doesnt quite make sense..
but you can always write an insert as select statement instead of what i think you are describing
Cursors are best to use when an column value form one table will be used repeatedly in multiple queries on different tables.
Suppose the values of id_test column are fetched from MY_TEST_TBL using a cursor CUR_TEST. Now this id_test column is a foreign key in MY_TEST_TBL. If we want to use id_test to insert or update any rows in table A_TBL,B_TBL and C_TBL, then in this case it's best to use cursors instead of using complex queries.
Hope this might help to understand the purpose of cursors

Resources