MS SQL 2005 compare field containing square parenthesis - sql

I am using MS SQL Server 2005 (9.0.4035) and trying to find rows that contain the same data in a nvarchar(4000) field. The field contains xml that has both opening and closing square parentheses.
Here is sample data:
DataID Data
1 1
2 1
3 2]
4 2]
5 3[
6 3[
Using the 'like' operator I expected to get 3 matching pairs, but my problem is that row 5 and 6 do not match each other, I only get back that rows 1 & 2 match, and 3 & 4 match.
I know MS SQL 2005 added regular expression support in queries but I did not expect them to evaluate field data as a regular expression, which I think it is doing. Is there a mode that I need to enable to get the proper results?
Any help appreciated,
Ryan
Edit: Added sql statement used:
Select t1.DataID, t2.DataID From TestTable t1, TestTable t2
Where t1.DataID <> t2.DataID
and t1.Data like t2.Data
Edit: Answer
Using '=' operator works, but escaping the '[' does not.

Change your query to use = instead of LIKE and you'll get the results that you expect. SQL 2005 T-SQL won't do regex - you'd need to use CLR functions for that - but the LIKE statment does do pattern matching. '[' and ']' are reserved for the pattern matching in a like statment, and you'd have to escape them out if you intended for them to be equality matches.
See http://msdn.microsoft.com/en-us/library/ms179859.aspx for info on the LIKE statement.
Either of the 2 queries below solved the problem in my tests...
--using equals operator...
Select t1.DataID, t2.DataID From TestTable t1, TestTable t2
Where t1.DataID <> t2.DataID
and t1.Data = t2.Data
--using replace to add an escape character.
Select t1.DataID, t2.DataID From TestTable t1, TestTable t2
Where t1.DataID <> t2.DataID
and t1.Data like REPLACE(t2.Data, '[', '\[') escape '\'

Related

hive or impala function to get substring of a string

My string(its a hive query) is having many FROM and JOIN statements and i want to use Regex function to get all the sub-strings after these statements.
Below is the sample string:
str=
'select col1, col2, col3 from dbname.table1,table2
left JOIN table3
on id=id
cross JOIN table4
where filter='check'
AND row<1
AND id=5'
Required output should be:
Ex:
select Regex(str,'from ') => dbname.table1,table2
select Regex(str,'JOIN ') => table3 table4
You can use the following regular expression to capture the tables followed by FROM or JOIN keyword.
((JOIN|join|From|from)\s)\w+((\.|,)\w+){0,}
Note that I have used keywords in simple and capital format. You can use only one format if the query string is consistent with the regex or you can do a case insensitive match.
The above regex will give the following result.
Case 1 : From
Full Match: from dbname.table1,table2
Match Group1: from (note the space at the end)
Case 2 : Join
Full Match: JOIN table3 and JOIN table4
Match Group1: JOIN (note the space at the end)
On every match, now you can use match group1 result to replace the unwanted prefix (from or JOIN ) from the full match result to get the table names.
Use this site to play and learn regex: https://regex101.com/
EDIT 1
In hive
regexp_extract('fooblabar', 'foo(.*?)(bar)', 1)
will give you the first group. In this case, it's bla
EDIT 2
Small update on the regular expression to capture the result in group3
((JOIN|join|From|from)\s)(\w+((\.|,)\w+){0,})
This should do the trick
select split(trim(regexp_replace('select Id from test1 where join test2','((JOIN|join|From|from)\s)(\w+((\.|,)\w+){0,})',' $3')),' ');

MSAccess - SQL query everything to the right OR left of a character

Using Ms Access 2016 I'm trying to run a SELECT query to match strings on a column from table1 and table2. I can do this with the following:
SELECT *
FROM table1 AS a, table2 AS b
WHERE a.luCode LIKE b.Code
table1.luCode only eve rhas one code, however, table2.Code sometimes has two codes in it separated by ";":
table2.Code
--------------------
someCode1
someCode2
someCode3;someCode4
someCode5
How can I perform the above query checking both to the left and right of the ";"?
So far I've been trying to use InStr (just to the left) using:
SELECT *
FROM table1 AS a, table2 AS b
WHERE a.luCode LIKE LEFT(b.Code,(InStr(1,b.Code,";"))-1);
But I get a datatype mismatch.
Figuring this would be either "null" values of empty strings (after checking it seems it's empty strings) I can add an IIF statement:
SELECT *
FROM table1 AS a, table2 AS b
WHERE IIF(b.Code<>"",a.luCode LIKE LEFT(b.Code,(InStr(1,b.Code,";"))-1));
This throws an "invalid procedure call" error.
I could just make a new column with the data after the ";" but there must be a way to do this with InStr.
First, this is a really, really bad data format. You should have a table with one row for each code, instead of throwing them together in a string.
Sometimes, we are stuck with other people's bad design decisions. In this case, you can try:
WHERE ';' & b.luCode & ';' LIKE '*;' & a.Code & ';*'
Or alternatively use instr() with the same logic.

How to use MINUS in google bigquery?

I am trying to do MINUS on 2 tables which have same schema in big-query.As I understand MINUS is not working in biquery
You can do something like:
SELECT
field
FROM `project_id.dataset.tableA` A
WHERE NOT EXISTS(SELECT 1 FROM `project_id.dataset.tableB` b WHERE a.field = b.field)
I see that there is EXCEPT set operator in Big Query for Standard SQL.
The EXCEPT operator returns rows from the left input query that are not present in the right input query. This is similar to what the MINUS does in ORACLE/MySQL
SELECT fieldId from dataset.table1 except DISTINCT SELECT fieldId from dataset.table2
Note: the datatype of both the columns should be same in both the tables

SQL 2005 Combine multiple record into one

I have a SQL Server 2005 table that records each step of a process as shown below
Time   Name
08.40  Sarah
09.00  Nafira
09.00  Sarah
09.00  Denur
10.00  MuLyono
10.00  Lucky
08.30  MaLa
08.35  Mara
What I would like to do is display a result that has a single line for each ResourceID that shows the time for each event.
Time   Name
08.30  MaLa
08.35  Mara
08.40  Sarah
09.00  Nafira, Sarah, Denur
10.00  MuLyono, Lucky
Any suggestions on how to accomplish this? Thanks for reading and answer ^_^
Try this. I have tested it and it is working.
SELECT t.Time, LEFT(Names , LEN(Names )-1) as Names
FROM yourtable t
CROSS APPLY
(
SELECT t1.Name + ','
FROM yourtable t1
WHERE t.Time= t1.Time
FOR XML PATH('')
) pre_trimmed (Names)
GROUP BY Time, Names;
As you can see, the join of strings from NAME column is done using CROSS APPLY. The http://technet.microsoft.com defines 'APPLY' as
The APPLY operator allows you to invoke a table-valued function for each row returned by an outer table expression of a query. The table-valued function acts as the right input and the outer table expression acts as the left input. The right input is evaluated for each row from the left input and the rows produced are combined for the final output. The list of columns produced by the APPLY operator is the set of columns in the left input followed by the list of columns returned by the right input.
While 'CROSS APPLY' as,
CROSS APPLY returns only rows from the outer table that produce a result set from the table-valued function.
The LEFT(Names , LEN(Names )-1) just trims the resulting string by one character, i.e. removes the extra comma at the end.
I modified your sql code into like this and this is work like i want.
select c1.Time,
stuff((select distinct ', '+cast(Nama as varchar(200))
from tbclientdata c2 where c2.time=c1.time
for xml path('')),1,1,'')
from tbclientdata c1
group by c1.Time

Matching records with wild cards from two different tables

I have two tables with the following data (amongst other data).
Table 1
Value 1
'003232339639
'00264644106272
0026461226291#
I need to match the second column in the table below using column 1 as an identifier
Table 2
Value 1 Value 2
00264 1
0026485 2
0026481 3
00322889 4
00323283 5
00323288 6
So the results I need will be as follows:
Result
Table 1, Value 1 Table 2, Value 2
'003232339639......4
'00264644106272....1
0026461226291#.....1
Any help will be appreciated - very stuck here and doing it manually at the moment in excel.
I hope this format makes sense - first time I am using this forum.
Melany, the question is kind of confusing (not written correctly) perhaps that's why no one is responding. I'll make an attempt to explain how similar selects is done
SELECTING DATA FROM TABLE1 WHERE A MATCHING COLUMN (COL1) EXISTS IN BOTH TABLE
SELECT * FROM TABLE1
INNER JOIN TABLE2
ON TABLE1.COL1 = TABLE2.COL1
AND TABLE1.COL1 = 'XYZ'
USING A SUBSELECT FOR THE SAME
SELECT * FROM TABLE1
WHERE COL1 IN(SELECT COL1 FROM TABLE2
WHERE COL1 = 'XYZ')
In SQL, the wildcard for one or more characters is %, and is to be used with the keyword LIKE.
So I suggest the following (if your purpose is really to match rows in Table1 for which Value1 begins like a value in Table2.Value1):
SELECT Table1.Value1, Table2.Value2 WHERE Table1.Value1 LIKE CONCAT(Table2.Value1, '%');
Edit: replace CONCAT(x, y) with x || y for some DBMSs (SQLite for instance).