SQL: how to add condition, where some characters have same value - sql-server

I have 2 tables: "table1" and "table2" and in these tables, I have hundred of names. Now I want to select only these names, where first 4 character have the same value.
So far it is not so difficult. Something like this:
select * from table1
join table2 on LEFT(table1.name,4)=LEFT(table2.name,4)
But I am struggling to add one condition that some characters have same value, for example: i=y, v=w, c=k and vice versa.
If table1 has name "Citty" and table2 has name "Kitty", I want this name also comes out in results

You should look into SOUNDEX() and DIFFERENCE() functions of SQL Server. These are available with full text search.
Alternatively, you can create a clr function and call it from sql.

Related

Updating a table column using multiple data from another table

I have 2 tables Awards_Nominations and custom_1, and I need to update Awards_Nominations.Add14 column with the concatenations of custom_1.awardNames.
Conditions should have :
Add1 >= GPA
Majors like Add3 or 'AllMajors'
AcademicReq like Add2 or 'High School Student'
Universities like Add4 or 'AllUniversities'
sample Awards_Nominations
sample custom_1
I tried with the update statement inner join but it does not update.
UPDATE [dbo].[Awards_Nominations]
SET Add14=Add14+','+awardName
from [Awards_Nominations] a
inner join custom_1 on right([Add1],3)>=GPA and (Majors like '%'+Add3+'%' or Majors='AllMajors')
and (AcademicReq like '%'+Add2+'%' or 'High School Student' like '%'+AcademicReq+'%') and (Universities like '%'+Add4+'%' or Universities='AllUniversities')
where n_AwardID=4 and ApprovalStatus='final' and Add1<>''
GO
My end goal is to have something like below:
sample updated Awards_Nominations
With an update that matches multiple records, the last update wins. The source column value is not updated for use as input later. (It's sort of like the "inserted" table in a trigger that represents the data before the query.) You want to concatenate data from multiple rows into a single value. There are plenty of examples out there. I prefer XML myself. I will try STRING_AGG the next time I need to do this.
How to concatenate text from multiple rows into a single text string in SQL server?

Fetching results from inner query having comma separated values - SQL Server

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.

SQL How to compare if a variable is the same as a value in a database column?

The problem I have is the following:
I work with a ticket system that uses plugins to realize workflows.
In this case I use SQL to presort incoming emails.
The SQL query looks like this:
SELECT Count(Case when {MSG_CC_002_DeviceReg_MailBody} LIKE '%You have received an invoice from%' Then 1 END);
What I want to do now is instead of using LIKE and then a certain phrase like above, I want to compare this to a column in a database table that contains all necessary phrases.
The table has only two columns, phraseID and phrase.
{MSG_CC_002_DeviceReg_MailBody} is the variable that needs to compared against the values of the column.
So if the variable matches with an entry in the column it should just return 1.
[Edit:]
This is just one of the things I want to use this for, I also have a variable {MSG_CC_002_DeviceReg_MailSender} that will provide the email address that I want to compare to a similar table that contains email addresses.
Is this possible?
If so - how?
You can use join or a subquery:
select count(*)
from t
where exists (select 1
from othertable ot
where {MSG_CC_002_DeviceReg_MailBody} LIKE '%' + ot.phrase + '%'
) ;
This will be dog-slow if you have a lot of phrases or email addresses, but it'll give you what you want.
SELECT COUNT(*) AS RetValue
FROM PhraseTable
WHERE {MSG_CC_002_DeviceReg_MailBody} LIKE '%' + phrase + '%';
Yes it is possible, you can achieve this with using dynamic query. Basically you need to construct your query as a string then execute it.
You can find examples and more information about dynamic query within the following link;
https://www.mssqltips.com/sqlservertip/1160/execute-dynamic-sql-commands-in-sql-server/

Mixing indexed and calculated fields in a table-valued function

I work with SQL Server 2008, but can use a later version if it would matter.
I have 2 tables with pretty similar data about some people but in different formats (no intersections between these 2 sets of people).
Table 1:
int personID
bit IsOldPerson //this field is indexed
Table 2:
int PersonID
int Age
I want to have a combined view that has the same structure as the Table 1. So I write the following script (a simplified version):
CREATE FUNCTION CombinedView(#date date)
RETURNS TABLE
AS
RETURN
select personID as PID, IsOldPerson as IOP
from Table1
union all
select personID as PID, dbo.CheckIfOld(Age,#date) as IOP
from Table2
GO
The function "CheckIfOld" returns yes/no depending on the input age at the date #date.
So I have 2 questions here:
A. if I try select * from CombinedView(TODAY) where IOP=true, whether the SQL Server will do the following separately: 1) for the Table 1 use the index for the field IsOldPerson and do a "clever" index-based selection of results; 2) for the Table 2 calculate CheckIfOld for all the rows and during the calculation pick up or rejecting rows on the row-by-row basis ?
B. how can I check the execution plan in this particular case to understand whether my guess in the question (A) is correct or not?
Any help is greatly appreciated! Thanks!
Yes, if the query isn't too complex, the query optimizer should "see through" the view into its constituent UNION-ed SELECT statements, evaluate them separately, and concatenate the results. If there is an index on Table1, it should be able to use it. I tested this using tables we had and the same function concepts you presented. I reviewed the query plans of the raw SELECT to Table1 and the SELECT to the inline table-valued function with the UNION and the portion of the query plan relevant to Table1 was the same-- and it used the index.
Now if performance is a concern, I suggest you do one of two things:
If (a) Table2 is read-heavy rather than write-heavy, (b) you have the space, and (c) you can write CheckIfOld as a single CASE statement (as its name and context in your question implies), then you should consider creating a persisted calculated field in Table2 with the calculation from IsOldPerson and applying an index to it.
If Table2 is write-heavy, or you have no space for additional fields, you should at least consider converting CheckIfOld into an inline function. You will likely reap performance gains, depending on how it is used. In your case, it would be used like this:
select personID as PID, IOP.IsOldPerson from Table2 CROSS APPLY dbo.CheckIfOld(Age,#date) AS IOP

SQL query join elements

I will re-write my doubt to be more easy to understand.
I have one table named SeqNumbers that have only one column of data named PossibleNumbers, that has value from 1 to 10.000.
Then I have another Table named Terminals and one of the columns have the serial numbers of the terminals. What I want is get all the SerialNumbers that not exists in the Terminals table from 1 to 10.000.
I've created the SeqNumbers table only to do this... maybe there's another solution without using it... that's fine to me.
The query I have is:
SELECT PossibleNumbers from SeqNumbers
Where PossibleNumbers NOT IN (SELECT SerialNumbers from Terminals)**
Basically I want to list ALL serial numbers of terminals that doesn't exists in the database.
This Query works fine I think... but the problem is that I don't want all results in a single column.. I want these results displayed in 4 or 5 columns.
For my purpose I can only use the results from the query like that. I cannot use programmatically methods to do that.
Hope this is more clear now... Thanks for all the help...
select x, x+1000 from tablename
Will that do it for you?
If I'm reading this right, you'd probably have to do a self join; something like:
SELECT
LeftValues.ColA,
RightValues.ColA AS ColB
FROM YourTable LeftValues
LEFT JOIN YourTable RightValues ON LeftValues.ColA = RightValues.ColA - 1000
WHERE LeftValues.ColA < 1000
Note: Use the JOIN that makes sense for you (left if you are willing to accept NULLs in ColB, inner if you only want them where both values exist)
You can use a scripting language to parse the MySQL results to format it anyway you like. Are you using PHP to access the database? If so, let me know and I can cook one up for you.
I just saw your new updated question. In this case the order of the columns will be ordered by your SELECT statement and you can also sort too. Here is an example:
SELECT Column1, Column2 FROM my_table ORDER BY Column1, Column2 ASC

Resources