I have two columns with similar data (shown below)
Table1
CHMedicalCorpINC
UniversalStd
SummitCorp
Table2
CHMedicalCorp
UniversalStdOrlando
SummitCorpINC
I want to compare the two columns letter by letter; if I am using substring then it displays values which match up 13 letters or those which have perfect match.
So the output gives me only the CHMedicalCorp not the other two columns. And I want the other two columns to be displayed
SUBSTRING(a.table1, 1, 13) = SUBSTRING(c.table2, 1, 13)
I want it to show me anything that matched up to 13 or less. Is there a way to do that or a function which allows me to do that?
The query below will work if it has any Id in the table.
SELECT T1.*
FROM TableName T1
JOIN TableName T2 ON T2.Id = T1.Id
WHERE T1.Table1 like '%' + T2.Table2 + '%'
OR T2.Table2 like '%' + T1.Table1 + '%';
If there is no Id in the table, you can use this way:
SELECT T1.*
FROM TableName T1, TableName T2
WHERE T1.Table1 like '%' + T2.Table2 + '%'
OR T2.Table2 like '%' + T1.Table1 + '%'
Sample execution with given data:
DECLARE #TestTable TABLE (Id INT, Table1 VARCHAR (100), Table2 VARCHAR (100));
INSERT INTO #TestTable (Id, Table1, Table2) VALUES
(1, 'CHMedicalCorpINC', 'CHMedicalCorp'),
(2, 'UniversalStd', 'UniversalStdOrlando'),
(3, 'SummitCorp', 'SummitCorpINC'),
(4, 'Hello', 'Welcome');
SELECT T1.*
FROM #TestTable T1
JOIN #TestTable T2 ON T2.Id = T1.Id
WHERE T1.Table1 like '%' + T2.Table2 + '%'
OR T2.Table2 like '%' + T1.Table1 + '%'
Related
I want move the last 3 characters of each line of data to the next line, the first line fill with xxx.
example:
now i have TableOne, i want get TableTwo, thanks!
[update]
mysql version is 5.7.22, not support lag function
If your version of MySql/MariaDB supports window functions and you have already created TableTwo you can insert the new rows like this:
insert into TableTwo(id, num)
select
id,
concat(
coalesce(lag(right(num, 3)) over (order by id), 'xxx'),
coalesce(left(num, 2), '')
) num
from (
select * from TableOne
union all
select max(id) + 1, null from TableOne
) t;
See the demo.
Without window functions you can do it with a self join:
insert into TableTwo(id, num)
select
t.id,
concat(
coalesce(right(t1.num, 3), 'xxx'),
coalesce(left(t.num, 2), '')
) num
from (
select * from TableOne
union all
select max(id) + 1, null from TableOne
) t left join TableOne t1
on t1.id = t.id - 1;
See the demo.
Results:
> id | num
> -: | :----
> 1 | xxxab
> 2 | cde01
> 3 | 23456
> 4 | 789
I need to create a select statement in this way:
SELECT * FROM mytable where COUNT_CHARACTER('-', mycolumn) = 2
It select all rows where the character '-' is present exactly two times in all records.
Is there a function in MySQL as this COUNT_CHARACTER?
This may play trick
SELECT * FROM mytable
WHERE (LENGTH(mycolumn) - LENGTH(REPLACE(mycolumn, '-', '')))=2;
This expression usually does the trick.
LENGTH(MyField) - LENGTH( REPLACE ( MyField , '-', '') )
...
SELECT
(
SELECT
MyField,
FoundCount = LENGTH(MyField) - LENGTH( REPLACE ( MyField , '-', '') )
FROM
MyTable
)AS X
WHERE
FoundCount>2
Is it possible to use only sql query no procedural language to get below format output
ID Name
-------------
1 a,b,c
2 x,y,z
3 m,n,l
I want this to print like below
1:a
1:b
1:c
2:x
2:y
2:z
Is this is possible with only my sql query or I have to use UDF ?
Yes you can-
The solution below is for Mysql.
You can use SUBSTRING_INDEX to reverse the process of 'group_concat'.
Here is your sql-
SELECT
id,
SUBSTRING_INDEX(SUBSTRING_INDEX(names, ',', n.d+1), ',', -1) name
FROM
users
INNER JOIN
(SELECT 0 d UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) n
ON LENGTH(REPLACE(names, ',' , '')) <= LENGTH(names)-n.d
ORDER BY
id,
n.d
;WITH CTE(ID,Name)
AS
(
SELECT 1,'a,b,c' union all
SELECT 2,'x,y,z' union all
SELECT 3,'m,n,l'
)
SELECT ID, Split.a.value('.', 'VARCHAR(100)') AS Data
FROM
(
SELECT ID,
CAST ('<M>' + REPLACE(Name, ',', '</M><M>') + '</M>' AS XML) AS Data
from CTE
) AS A CROSS APPLY Data.nodes ('/M') AS Split(a);
If you want ouput with ':' separter ,below is the code
;WITH CTE(ID,Name)
AS
(
SELECT 1,'a,b,c' union all
SELECT 2,'x,y,z' union all
SELECT 3,'m,n,l'
)
SELECT CONCAT(CAST(ID AS VARCHAR(5)),' : ', CAST(Data AS VARCHAR(5))) As [OutPut] From
(
SELECT ID, Split.a.value('.', 'VARCHAR(100)') AS Data
FROM
(
SELECT ID,
CAST ('<M>' + REPLACE(Name, ',', '</M><M>') + '</M>' AS XML) AS Data
from CTE
) AS A CROSS APPLY Data.nodes ('/M') AS Split(a)
)Final
In SQL server, you could do it by a query with CROSS APPLY and xml query
DECLARE #SampleData AS TABLE (ID int IDENTITY (1,1), Name varchar(100))
INSERT INTO #SampleData (Name)
VALUES ('a,b,c'), ('x,y,z'), ('m,n,l')
;WITH temp AS
(
SELECT *,
CAST('<x>' + replace(sd.Name, ',', '</x><x>') + '</x>' AS xml) AS xmlText
FROM #SampleData sd
)
SELECT CONCAT(t.ID, ':',v.x.value('.','varchar(50)')) AS Result
FROM temp t
CROSS APPLY
t.xmlText.nodes('/x') AS v(x)
Demo link: http://rextester.com/IHQF16100
How do I get the average from multiple columns?
for example:
Columns: ID 125Hz 250Hz 500Hz 750Hz 1000Hz 1500Hz 2000Hz 3000Hz 4000Hz 6000Hz 8000Hz
Values: 1 92 82 63 83 32 43 54 56 54 34 54
I want to get the average of all the columns except the ID. How do I do that?
You have to manually add the columns since there's no available built-in functions for horizontal aggregation.
select (125Hz+250Hz+500Hz+750Hz+1000Hz+1500Hz+2000Hz+3000Hz+4000Hz+6000Hz+8000Hz)/11 as aveHz from table_name
In SQL-SERVER you can use this
DECLARE #total int
DECLARE #query varchar(550)
DECLARE #ALLColumns VARCHAR(500)
SET #ALLColumns = ''
----Build the string columns
SELECT #ALLColumns = #ALLColumns + '+' + '['+sc.NAME+']'
FROM sys.tables st
INNER JOIN sys.columns sc ON st.object_id = sc.object_id
WHERE st.name LIKE '%YOUR_TABLE_NAME%'
AND sc.NAME LIKE '[0-9]%';--[0-9]% just get the column that start with number
----Get the total number of column,
SELECT #total = count(*) FROM sys.tables st
INNER JOIN sys.columns sc ON st.object_id = sc.object_id
WHERE st.name LIKE '%YOUR_TABLE_NAME%'
AND sc.NAME LIKE '[0-9]%';--[0-9]% just get the column that start with number
SET #query = 'SELECT SUM('+ SUBSTRING(#ALLColumns,2,LEN(#ALLColumns))+')/'
+CAST(#total as varchar(4))+ ' AS [AVG]
FROM [YOUR_TABLE_NAME]
GROUP BY [ID]'
--SELECT #query
EXECUTE(#query)
This will execute a query like this one:
SELECT SUM([125Hz]+[250Hz]+[500Hz]+[750Hz]+[1000Hz]+[1500Hz]+[2000Hz]
+[3000Hz]+[4000Hz]+[6000Hz]+[8000Hz])/11 AS [AVG]
FROM [YOUR_TABLE_NAME] GROUP BY [ID]
UPDATE
Add a column to store the avg, I called it [AVG] and chage the value of #query to
SET #query = '
CREATE TABLE #Medition (ID int,[AVG] decimal(18,4))
INSERT INTO #Medition (ID,[AVG])
SELECT ID,SUM ('+ SUBSTRING(#ALLColumns,2,LEN(#ALLColumns))+')/'
+CAST(#total as varchar(10))
+ ' AS [AVG] FROM Medition GROUP BY ID
UPDATE YOUR_TABLE_NAME SET YOUR_TABLE_NAME.[AVG] = #Medition.[AVG]
FROM YOUR_TABLE_NAME INNER JOIN #Medition ON YOUR_TABLE_NAME.ID =#Medition.ID
DROP TABLE #Medition
'
Note: Build queries string is a little ugly
Another way to do it, without actually using the magic number 11, be it a little more verbose.
WITH t1 AS
(
SELECT * FROM myTable
WHERE (...) -- Should limit result to 1 row
),
t2 AS
(
SELECT col1 FROM t1
UNION ALL
SELECT col2 FROM t1
UNION ALL
(...)
)
SELECT AVG(col1) FROM t2;
this will display Average value of all that fields of each ID you have.
SELECT AVG(125Hz+250Hz+500Hz+750Hz+1000Hz+1500Hz+2000Hz+3000Hz+4000Hz+6000Hz+8000Hz)
AS Average FROM table
GROUP BY ID
SELECT sum(125Hz + 250Hz + 500Hz + 750Hz + 1000Hz + 1500Hz + 2000Hz + 3000Hz +
4000Hz + 6000Hz + 8000Hz)/11 as averageHz from TABLE
I have a table as below
DECLARE #T TABLE(Data VARCHAR(MAX))
INSERT INTO #T
SELECT 'SQL' UNION ALL SELECT 'JOB'
need output as below but without using any UDF.
Data String
------------
SQL S,Q,L
JOB J,O,B
Please help me on this
Sure you can :). You can make it shorter too...
DECLARE #T TABLE(Data VARCHAR(MAX))
INSERT INTO #T
SELECT 'SQL' UNION ALL SELECT 'JOB';
With cte as
(
Select Data, Len(Data) DataLength, 1 level
From #t
Union All
Select Data, DataLength - 1, level + 1
From cte
Where DataLength > 1
),
cte2 as
(
Select Data, SUBSTRING(Data, DataLength, 1) DataLetter, level
From cte
),
cte3 as
(
Select Data,
(
SELECT DataLetter + ','
FROM cte2 c
Where c.Data = cte2.Data
Order By level desc
FOR XML PATH(''), TYPE
).value('.[1]', 'NVARCHAR(1000)') DataComa
From cte2
Group By Data
)
Select Data, substring(DataComa, 1, Len(DataComa) - 1) Data2
From cte3
Late to the party, but here's a slightly shorter version:
DECLARE #T TABLE(Data VARCHAR(MAX));
INSERT INTO #T VALUES('SQL'),('JOB'),('FLOOB');
;WITH n AS (SELECT TOP (SELECT MAX(LEN(Data)) FROM #T)
n = ROW_NUMBER() OVER (ORDER BY [object_id]) FROM sys.all_objects
),
t AS (SELECT n, Data, Letter = SUBSTRING(t.Data, n.n, 1) FROM n
INNER JOIN #T AS t ON SUBSTRING(t.Data, n.n, 1) > ''
)
SELECT Data, STUFF((SELECT ',' + letter FROM t AS t2
WHERE t2.Data = t.Data ORDER BY t2.n FOR XML PATH(''),
TYPE).value(N'./text()[1]', N'varchar(max)'), 1, 1, '')
FROM t GROUP BY Data;
Results:
FLOOB F,L,O,O,B
JOB J,O,B
SQL S,Q,L
It is very easy to do with UDF.
But If you want with out UDF, the only one way I can think of is
something like this
DECLARE #T TABLE(Data VARCHAR(MAX))
INSERT INTO #T
SELECT 'SQL' UNION ALL SELECT 'JOB'
select replace(replace(replace(data,'S','S,'),'Q','Q,'),'L','L,') from #T
here you have to replace all the 26 characters with replace function. ie, 'A' with 'A,' 'B' with 'B,' .... 'Z' with 'Z,'
Using the same approach I used for Initcap function here http://beyondrelational.com/modules/2/blogs/70/posts/10901/tsql-initcap-function-convert-a-string-to-proper-case.aspx
DECLARE #T TABLE(Data VARCHAR(MAX))
INSERT INTO #T
SELECT 'SQL' UNION ALL SELECT 'JOB'
select data,
upper(replace(replace(replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(
' '+data ,
' a','a,'),' b','b,'),'c','c,'),'d','d,'),'e','e,'),'f','f,'),
' g','g,'),' h','h,'),'i','i,'),'j','j,'),'k','k,'),'l','l,'),
' m','m,'),' n','n,'),'o','o,'),'p','p,'),'q','q,'),'r','r,'),
' s','s,'),' t','t,'),'u','u,'),'v','v,'),'w','w,'),'x','x,'),
' y','y,'),' z','z,')) as splitted_data
from
#t