Query to find records following same sequence of patterns? - sql

How to find records which matches certain sequences from the below table:
ID s_id task
1 1 a
1 2 b
1 3 b
1 4 c
1 5 c
1 6 d
1 7 a
2 1 a
2 2 c
2 3 c
3 1 a
3 2 b
3 3 c
3 4 d
1 1 a
1 2 b
1 3 c
1 4 c
1 5 e
1 6 d
How to fetch the records following the below pattern
a
1 or more b
c

Below code will transform your data to a list of site visits (id) followed by a single string of characters representing pages visited (e.g. "abbbcd").
SELECT t2.id, max(tasks) as tasks from
(
SELECT t1.id,
(SELECT '' + Task FROM [Table] WHERE id = t1.id ORDER BY s_Id FOR XML PATH('')) AS tasks
from [Table] t1
) t2
group by t2.id
So the problem is now reduced to searching for a pattern of characters: a--any number of b's--c. You can use LIKE to do this:
SELECT *
FROM (
SELECT t2.id, max(tasks) as tasks from
(
SELECT t1.id,
(SELECT '' + Task FROM [Table] WHERE id = t1.id ORDER BY s_Id FOR XML PATH('')) AS tasks
from [Table] t1
) t2
group by t2.id
) t3
WHERE t3.tasks LIKE '%abc%'
OR t3.tasks LIKE '%abbc%'
OR t3.tasks LIKE '%abbbc%'
OR t3.tasks LIKE '%abbbbc%';
This is a bit crude. You want to say any number of b's, but LIKE does not support that. This is what regular expressions (RegEx) is normally used for. The expression would be "ab+c" which stand for: "a" followed by 1 or more "b"s, followed by a "c".
Unfortunately, SQL server does not support regex (Oracle does), so you have to use CLR to implement it. Others have done this for you, so you can follow instructions here to install it: https://www.simple-talk.com/sql/t-sql-programming/clr-assembly-regex-functions-for-sql-server-by-example/

Related

SQL Select all rows per group if a condition is met at least once

I have a table variable that looks like this:
id
V1
V2
1
A
1
1
A
2
1
B
3
2
C
2
2
A
3
3
A
1
3
A
2
3
B
2
4
C
3
5
A
2
I would like to select only the ids where at least one V2 = 3, to get something like this:
id
V1
V2
1
A
1
1
A
2
1
B
3
2
C
2
2
A
3
4
C
3
What is the SQL query to do this?
Select *
From yourtable
where id in (
select distinct id
from yourtable
where v2 = 3
)
Try:
select v.* from variable01 v where id in (select distinct id from variable01 where V2=3 ) ;
Working demo : http://sqlfiddle.com/#!9/dd7175/1
For this type of problem, I usually recommend exists because it optimizes better across more databases (with the right indexing):
select v.*
from variable v
where exists (select 1
from variable v2
where v2.id = v.id and
v2.v2 = 3
);
You can also express this quite well using in. But importantly, select distinct is not needed in the subquery:
select v.*
from variable v
where v.id in (select v2.id
from variable v2
where v2.v2 = 3
);

Need help in creating SQL

I have table with following schema and contains records-
id parent_id active
1 NULL Y
2 1 Y
3 1 N
4 NULL Y
5 4 N
6 NULL N
7 6 N
I need to write a SQL for following use case:
Need to find all records whose active not equals to Y and whose parent_id active equals to Y.
Example output of above should be as follows:
output should be-
id parent_id active
3 1 N
5 4 N
You could do it using self join as below:
SELECT *
FROM mytab t1 INNER JOIN mytab t2
ON t1.id = t2.parent_id
WHERE t1.active != 'Y'
AND t2.active = 'Y'
You can do this using self-join as following:
select t1.id,t1.parent_id,t1.active
from test t1 inner join test t2 on t1.parent_id=t2.id
where t1.active <> 'Y' and t2.active='Y';
Results can be seen here:
DB Fiddle Demo
use subquery 1st take all the id's who have active=Y then check with parent_id and active column
select * from tbale_name where
parent_id in (
select id from table_name where active='Y'
) and active='N'
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=4a450a50a2ea6c3f4e1a19e2657ae35d
id parent_id active
3 1 N
5 4 N

How to get Oracle to return unique results in a one to many relationship tables with a left join

I have a three tables
Table 1
Id Department
1 A
2 B
3 C
4 D
Table 2
Id DepartId Name
1 1 ABC
2 1 DEF
3 1 ASD
4 2 FGH
5 2 HJK
6 3 ZXC
Table 3
Id Depart Area
1 A pp
2 B
3 C nn
4 D oo
I need the result
Id Depart Name Area
1 A ABC pp
2 B FGH Null
3 C ZXC nn
4 D NULL oo
I need one matching entry from table 2 and table 3 to corresponding entry in the table 1
Do a left join to also get t1 rows without any reference in the t2 table. GROUP BY to get only 1 row per Department.
select t1.id, t1.Department, min(t2.Name)
from t1
left join t2 on t1.id = t2.DepartId
group by t1.id, t1.Department
I think I would do this with a correlated subquery:
select t1.*,
(select t2.name
from t2
where t1.id = t2.DepartId and rownum = 1
) as t2name
from t1;
This saves the overhead of an aggregation. An index on t2(DepartId, name) is optimal for this query.
by the way not the answer to your specific question but if instead of just one you want all the names you can use listagg
SELECT t1.id,
department,
LISTAGG (name, ',') WITHIN GROUP (ORDER BY name) names
FROM t1, t2
WHERE t1.id = t2.departId(+)
GROUP BY t1.id, department
ORDER BY 1
ID Department Names
1 A ABC,ASD,DEF
2 B FGH, HJK
3 C ZXC
4 D

Merge data into one column - sql server 2012

How can I merge data into one column for different account numbers. Currently, it looks like this.
TableA.Order TableA.Question TableB.Response
1 a Null
1 b James
1 c Null
2 d Zebra
2 T Null
However, I want it to merge like below:
TableA.Order NewColumn
1 a
1 b
1 c
1 James
2 d
2 T
2 Zebra
Base from my understanding of your question. I devised a solution which answers to it. See my query below:
SELECT * FROM TableA
UNION ALL
SELECT B.Order1,A.Response From
(
(SELECT ROW_NUMBER()OVER(ORDER BY Response)PK,* FROM TableB) A Left Join
(SELECT ROW_NUMBER()OVER(ORDER BY Order1)PK,* FROM TableA) B On A.PK=B.PK
)
Where Response IS NOT NULL

How SQL join work?

i am using MYSQL..
I have two tables:
TABLE 1 (TABLE NAME T1)
SL NAME
1 a
2 b
3 c
4 c
table 2 (table name T2)
SL NAME
1 a
2 c
3 c
4 c
Q1: how i count the total number of 'c' in both table?
Q2: which name is max occurrences in both table?
sl is primary key...
my query is:>
select count(*) from t1,t2
where t1.name=t2.name where t1.name='c';
but it showing 6
To count c in both tables you should use UNION, not JOIN.
Syntax:
SELECT ...
UNION [ALL | DISTINCT] SELECT ...
[UNION [ALL | DISTINCT] SELECT ...]
Doc:
http://dev.mysql.com/doc/refman/5.0/en/union.html
Edit:
I'll explain the query that you provided.
select count(*) from t1,t2 where t1.name=t2.name where t1.name='c';
First of all, you use WHERE clause twice which is a syntax error. Should be:
select count(*) from t1,t2 where t1.name=t2.name AND t1.name='c';
And this is the same that:
SELECT count(*) from t1
JOIN t2 ON t1.name=t2.name
WHERE t1.name='c';
You choose only rows with c value so these are the rows, that we will take under consideration:
TABLE 1 (TABLE NAME T1)
SL NAME
3 c
4 c
table 2 (table name T2)
SL NAME
2 c
3 c
4 c
Now, simple JOIN joins every row from table 1 to every row from table 2 (where condition is true of course)
So the result before counting is:
t1.SL t1.NAME t2.SL t2.NAME
3 c 2 c
4 c 3 c
3 c 4 c
4 c 2 c
3 c 3 c
4 c 4 c
This is 6 rows.
Answers for both of your questions.
SELECT name, count(*) as cnt
FROM(select t1.name from t1
union all
select name from t2) as tem
group by name
order by cnt DESC
This query will give you ranking of names ordered by occurrences.
To retrieve only c count, just add WHERE clause. To retrieve only the most occurring name set LIMIT clause to 1.
INSERT INTO #test
SELECT NAME FROM m_t1 WHERE NAME ='c'
UNION all
SELECT NAME FROM m_t2 WHERE NAME ='c'
SELECT count(*) FROM #test