I am very new at PostgreSQL and want to be able to delete rows from a table if a specific column starts with a certain pattern.
For example,
I have a reference column which is a sort of time stamp (YYMMDDHHMM). If the reference column starts with 16********, then i'd like it to be deleted.
So far, I know how to delete the column if the whole reference is known. E.g:
DELETE FROM my_tbl WHERE name='test1' AND ref_no=1601010000;
However, I need to change this so that the condition only specifies the first 2 digits of the reference number.
Read about LIKE operator: https://www.postgresql.org/docs/8.3/static/functions-matching.html
Use this command to delete rows:
DELETE FROM my_tbl WHERE reference LIKE '16%'
Before deleting rows from the table, first check if a delete condition really works as expected using it in a regular SELECT statement:
SELECT * FROM my_tbl WHERE reference LIKE '16%'
If reference column is not of type varchar but for example int, you need first to conver (cast) it to a varchar datatype in this way:
SELECT * FROM my_tbl WHERE reference::varchar LIKE '16%'
DELETE FROM my_tbl WHERE reference::varchar LIKE '16%'
Try the 'like' operator, it allows you to do pattern matching.
DELETE FROM my_tbl WHERE name LIKE '%test%';
The '%' character is a wildcard. The above line should delete every column where the name contains the string 'test'.
More info here: pattern matching
Related
I have a temp table having two columns - key and value:
temp_tbl:
key value
---|-----
k1 | a','b
Below is the insert script with which I am storing the value in temp_tbl:
insert into temp_tbl values ('k1', 'a'+char(39)+char(44)+char(39)+'b');
Now, I want trying to fetch records from another table (actual_tbl) like this:
select * from actual_tbl where field_value in
(select value from tamp_tbl where key = 'k1');--query 1
But this is not returning anything.
I want the above query to behave like the following one:
select * from actual_tbl where field_value in
('a','b');--query 2
Where am I doing wrong in query 1?
I am using sql server.
Where am I doing wrong in query 1?
Where you are going wrong is in failing to understand the way the IN keyword works with a subquery vs a hard-coded list.
When an IN clause is followed by a list, each item in the list is a discrete value:
IN ('I am a value', 'I am another value', 'I am yet another value')
When it's followed by a sub-query, each row generates a single value. Your temp table only has one row, so the IN clause is only considering a single value. No matter how you try to "trick" the parser with commas and single-quotes, it won't work. The SQL Server parser is too smart to be tricked. It will know that a single value of 'a','b' is still just a single value, and it will look for that single value. It won't treat them as two separate values like you are trying to do.
I want a list of properties about a given table and for a specific record of data from that table - in one result
Something like this:
Column Name , DataLength, SchemaLengthMax
...and for only one record (based on a where filter)
So what Im thinking is something like this:
- Get a list of columns from sys.columns and also the schema-based maxlength value
- populate column names into a temp table that includes (column_name, data_length, schema_size_max)
- now loop over that temp table and for each column name, fetch the data for that column based on a specific record, then update the temp table with the length of this data
- finally, select from the temp table
sound reasonable?
Yup. That way works. Not sure if it's the best, since it involves one iteration per column along with the where condition on the source table.
Consider this, instead :
Get the candidate records into a temporary table after applying the where condition. Make sure to get a primary key. If there is no primary key, get a rowid. (assuming SQL Server 2005 or above).
Create a temporary table (Say, #RecValueLens) that has three columns : Primary_key_Value, MyColumnName, MyValueLen
Loop through the list of column names (after taking only the column names into another temporary table) and build sql statement shown in Step 4.
Insert Into #RecValueLens (Primary_Key_Value, MyColumnName, MyValueLen)
Select Max(Primary_Key_Goes_Here), Max('Column_Name_Goes_Here') as ColumnName, Len(Max(Column_Name)) as ValueMyLen From Source_Table_Goes_Here
Group By Primary_Key_Goes_Here
So, if there are 10 columns, you will have 10 insert statements. You could either insert them into a temporary table and run it as a loop. If the number of columns is few, you could concatenate all statements into a single batch.
Run the SQL Statement(s) from above. So, you have Record-wise, column-wise, Value lengths. What is left is to get the column definition.
Get the column definition from sys.columns into a temporary table and join with the #RecValueLens to get the output.
Do you want me to write it for you ?
I have a column in DB where it may contain data with special characters.
for ex:a column,Name may have data as following
santosh's
santosh/s
santosh%s
How to search for these values in DB using like operator.
Select * from table where name like '%santosh%';
How to change the above query to search for apostrophe(santosh's)
for 1. apostrophe s you can use
Select * from table where column like '%santosh''s%'
for 2. /s you can give directly
Select * from table where column like '%santosh/s%'
for 3. %s you can use
Select * from table where column like '%santosh[%]s%'
hope this helps.....
Just use 2 apostrophe to escape the character
Select * from table where name like '%santosh''s%';
Which one of the following queries is faster (LIKE vs CONTAINS)?
SELECT * FROM table WHERE Column LIKE '%test%';
or
SELECT * FROM table WHERE Contains(Column, "test");
The second (assuming you means CONTAINS, and actually put it in a valid query) should be faster, because it can use some form of index (in this case, a full text index). Of course, this form of query is only available if the column is in a full text index. If it isn't, then only the first form is available.
The first query, using LIKE, will be unable to use an index, since it starts with a wildcard, so will always require a full table scan.
The CONTAINS query should be:
SELECT * FROM table WHERE CONTAINS(Column, 'test');
Having run both queries on a SQL Server 2012 instance, I can confirm the first query was fastest in my case.
The query with the LIKE keyword showed a clustered index scan.
The CONTAINS also had a clustered index scan with additional operators for the full text match and a merge join.
I think that CONTAINS took longer and used Merge because you had a dash("-") in your query adventure-works.com.
The dash is a break word so the CONTAINS searched the full-text index for adventure and than it searched for works.com and merged the results.
Also try changing from this:
SELECT * FROM table WHERE Contains(Column, "test") > 0;
To this:
SELECT * FROM table WHERE Contains(Column, '"*test*"') > 0;
The former will find records with values like "this is a test" and "a test-case is the plan".
The latter will also find records with values like "i am testing this" and "this is the greatest".
I didn't understand actually what is going on with "Contains" keyword. I set a full text index on a column. I run some queries on the table.
Like returns 450.518 rows but contains not and like's result is correct
SELECT COL FROM TBL WHERE COL LIKE '%41%' --450.518 rows
SELECT COL FROM TBL WHERE CONTAINS(COL,N'41') ---40 rows
SELECT COL FROM TBL WHERE CONTAINS(COL,N'"*41*"') -- 220.364 rows
I need to create am index in SQL however it needs to display the records by entering only a part of the name. The index should be created to retrieve the student information using part of the student name (i.e. if the name if Johnanesburg; the user can input John)
I used the syntax below but it wont work
create index Student ON Student(SName)
SELECT * FROM Student WHERE StRegNo LIKE A%
go
I think your problem is here: A%
Try wrapping it in apostrophes.
SELECT *
FROM Student
WHERE StRegNo LIKE 'A%'
Also, you may want a GO statement after you create your index.
The index you are creating over SName will not provide as much benefit for the select statement you are running as one created over StRegNo. Assuming that StRegNo is the primary key on the Student table you could try:
CREATE CLUSTERED INDEX IX_Student on Student(StRegNo)
SELECT *
FROM Student
WHERE StRegNo LIKE 'A%'
However it appears that the SQL you have provided is at odds with your question. If you want to search based on student name then you might want the following instead.
CREATE NONCLUSTERED INDEX IX_Student on Student(SName)
SELECT *
FROM Student
WHERE SName LIKE 'A%'
Ardman got it right regarding your query %A => '%A'. Now as for the index, that's another story that no index can help you with at the time, neither can full text search. If you want to look for names starting with #A (i.e. John%), an ordered index could help but otherwise (i.e. %bur%), you will go for a full table scan !