Filter Out Rows with Matching Substring - sql

I have a query that returns rows that resemble this:
R123
R234
R345
J123
Is it possible to have the rows that have matching substrings to not be returned? So in this case R123 and J123 would not be shown in the results.

I've not tested this but it should give you an idea..
Inner join the receipts i.e. subset of the table where left(col,1) = 'r'
with the journals (subset of the table where left(col,1) = 'j) and you'll get a list of matching rows.
Then simply select the rows from the table which are not in this list
SELECT * FROM [Table]
WHERE SUBSTRING(col,2,100) NOT IN
(SELECT Receipts.Ref FROM
(SELECT SUBSTRING(col,2,100) Ref from [Table] WHERE LEFT(col,1) = 'R') Receipts
INNER JOIN (SELECT SUBSTRING(col,2,100) Ref from [Table] WHERE LEFT(col,1) = 'J') Journals ON Receipts.Ref = Journals.Ref)

select
Value
from MyTable
group by substring(Value,2,len(Value))
having count(*) = 1

Sure, how about this?
create table t1 (
t varchar(20)
)
go
insert into t1 (t) values ('R123'),('R234'),('R345'),('J123')
go
select Numerals
from (
select SUBSTRING(t,1,1) as Prefix, SUBSTRING(t,2,999) as Numerals
from t1) a
group by Numerals
having COUNT(*) = 1

Related

How to combine multiple SELECT statements into a single query & get a single result output

I have multiple SELECT queries which is ran against different tables.
The output of all the queries have the same number of rows (every query when ran individually will have the same number of rows). Is there a way I can combine the output of all these queries into a single result? (Keep out from first query and add the output of next query as a column to the output of the next query). I dont want to save these tables into database as I am just doing some validation testing.
Example:
SELECT AAA,BBB,CCC FROM Table1
SELECT Table2.DDD, Table1.AAA
FROM Table2
INNER JOIN Table1
ON Table1.AAA = Table2.AAA
I tried writing combining the query as
SELECT Table1.AAA,Table1.BBB,Table1.CCC,T1.DDD
FROM Table1,
(SELECT Table2.DDD, Table1.AAA
FROM Table2
INNER JOIN Table1
ON Table1.AAA = Table2.AAA)T1
I tried doing the above combined query, but instead of getting 11 rows as output (both queries above had result of 11 rows), I am getting 35 rows as output.
Hope the question made sense!
You'll need to specify a criteria to match each row the first query with which row of the second query.
If, for example, the column AAA is unique in both queries and you want to match rows with the same values you could do:
select a.*, b.*
from (
SELECT AAA,BBB,CCC FROM Table1
) a
full join join (
SELECT Table2.DDD, Table1.AAA
FROM Table2
INNER JOIN Table1
ON Table1.AAA = Table2.AAA
) b on b.aaa = a.aaa
If there aren't any clear matching rules, you can produce an artificial row number on each result set and use it to match rows. For example:
select
a.aaa, a.bbb, a.ccc,
b.ddd, b.aaa
from (
SELECT AAA, BBB, CCC,
row_number() over(order by aaa) as rn
FROM Table1
) a
full join join (
SELECT Table2.DDD, Table1.AAA,
row_number() over(order by table1.aaa, table2.ddd) as rn
FROM Table2
INNER JOIN Table1
ON Table1.AAA = Table2.AAA
) b on b.rn = a.rn
If you have several results and want to have all of them as additional columns you can simply use ",":
create table temp1 as select '1' as c1 from DUAL;
create table temp2 as select '2' as c2 from DUAL;
create table temp3 as select '3' as c3 from DUAL;
select a.c1, b.c2, c.c3 from temp1 a, (select c2 from temp2) b, (select c3 from temp3) c;
An alternative could also be that you want to have all the results as additional rows then you would use UNION ALL between the individual results.

missing rows, how to select values

How to accomplish this: I have bunch of numbers (for example: 2342423; 34443123; 3523423) and some of them are in my database table as primary key value. I want to select only those numbers, which are not in my table. What is the best way to do this?
If it is just a few numbers you can do
select tmp.num
from
(
select 2342423 as num
union all
select 34443123
union all
select 3523423
) tmp
left join your_table t on t.id = tmp.num
where t.id is null
If it is more than a few numbers you should insert these into a table and left join against that table like this
select twntc.num
from table_with_numbers_to_check twntc
left join your_table t on t.id = twntc.num
where t.id is null

Query a table that have 2 cols with multiple criteria

I have a table with the following structure and Example data:
Now I want to query the records that have value equals to # and #.
For example according to the above image, It should returns 1 and 2
id
-----
1
2
Also if the parameters were #, # and $ It should give us 1. Because only the records with id 1 have all the given values.
id
-----
1
You can use a group by and having to get the distinct Id's that contain a distinct count of the number of items you're looking for
SELECT Id
FROM Table
WHERE Value IN ('#','$')
GROUP BY Id
HAVING COUNT(DISTINCT Value) = 2
SELECT Id
FROM Table
WHERE Value IN ('#','$','#')
GROUP BY Id
HAVING COUNT(DISTINCT Value) = 3
SQL Fiddle you can use this link to test
There's several ways to do this.
The subquery method:
SELECT DISTINCT Id
FROM Table
WHERE Id IN (SELECT Id FROM Table WHERE Value = '#')
AND Id IN (SELECT Id FROM Table WHERE Value = '#');
The correlated subquery method:
SELECT DISTINCT t.Id
FROM Table t
WHERE EXISTS (SELECT 1 FROM Table a WHERE a.Id = t.Id and a.Value = '#')
AND EXISTS (SELECT 1 FROM Table b WHERE b.Id = t.Id and b.Value = '#');
And the INTERSECT method:
SELECT Id FROM Table WHERE Value = '#'
INTERSECT
SELECT Id FROM Table WHERE Value = '#';
Best performance will depend on RDBMS vendor, size of table, and indexes. Not all RDBMS vendors support all methods.
Maybe a multiple self join like this?
select
distinct t1.id
from
table t1
join table t2 on (t1.id=t2.id)
join table t3 on (t1.id=t3.id)
...
where
t1.value='#' and
t2.value='#' and
t3.value='$' and
...

Select rows having dstinct values for two fields

Pardon me for the title. I have a table like this:
There will be thousands of rows and now I want to select the rows having the same group_id but vr_debit and vr_credit values must not be equal: ie;, in the image shown, none of the rows satisfy this criteria. If there is are two rows, say, (6,500.000,0) and(6,0,600.000), I want them as the result. Hope you get the idea.
Thank you.
Calculate each group using SUM() which is an aggregate function and filter them using HAVING clause.
SELECT GROUP_ID, SUM(vr_debit) totalDebit, SUM(vr_credit) totalCredit
FROM TableName
GROUP BY GROUP_ID
HAVING SUM(vr_debit) <> SUM(vr_credit)
if you want to get the uncalculated rows, you can join it on the subquery.
SELECT a.*
FROM TableName a
INNER JOIN
(
SELECT GROUP_ID
FROM TableName
GROUP BY GROUP_ID
HAVING SUM(vr_debit) <> SUM(vr_credit)
) b ON a.GROUP_ID = b.GROUP_ID
SQLFiddle Demo (for both queries)
Perhaps:
SELECT group_ID,
vr_debit,
vr_credit
FROM
dbo.TableName T1
WHERE
EXISTS(
SELECT 1 FROM dbo.TableName T2
WHERE T1.group_ID = T2.group_ID
AND T1.vr_debit <> T2.vr_debit
AND T1.vr_credit<> T2.vr_credit
AND T1.vr_debit <> T2.vr_credit
)
Also you can use this option
SELECT *
FROM dbo.test64 t
WHERE EXISTS (
SELECT 1
FROM dbo.test64 t2
WHERE t.group_id = t2.group_id
HAVING SUM(t2.vr_debit) - SUM(t2.vr_credit) != 0
)
Demo on SQLFiddle

How do I compare 2 rows from the same table (SQL Server)?

I need to create a background job that processes a table looking for rows matching on a particular id with different statuses. It will store the row data in a string to compare the data against a row with a matching id.
I know the syntax to get the row data, but I have never tried comparing 2 rows from the same table before. How is it done? Would I need to use variables to store the data from each? Or some other way?
(Using SQL Server 2008)
You can join a table to itself as many times as you require, it is called a self join.
An alias is assigned to each instance of the table (as in the example below) to differentiate one from another.
SELECT a.SelfJoinTableID
FROM dbo.SelfJoinTable a
INNER JOIN dbo.SelfJoinTable b
ON a.SelfJoinTableID = b.SelfJoinTableID
INNER JOIN dbo.SelfJoinTable c
ON a.SelfJoinTableID = c.SelfJoinTableID
WHERE a.Status = 'Status to filter a'
AND b.Status = 'Status to filter b'
AND c.Status = 'Status to filter c'
OK, after 2 years it's finally time to correct the syntax:
SELECT t1.value, t2.value
FROM MyTable t1
JOIN MyTable t2
ON t1.id = t2.id
WHERE t1.id = #id
AND t1.status = #status1
AND t2.status = #status2
Some people find the following alternative syntax easier to see what is going on:
select t1.value,t2.value
from MyTable t1
inner join MyTable t2 on
t1.id = t2.id
where t1.id = #id
SELECT COUNT(*) FROM (SELECT * FROM tbl WHERE id=1 UNION SELECT * FROM tbl WHERE id=2) a
If you got two rows, they different, if one - the same.
SELECT * FROM A AS b INNER JOIN A AS c ON b.a = c.a
WHERE b.a = 'some column value'
I had a situation where I needed to compare each row of a table with the next row to it, (next here is relative to my problem specification) in the example next row is specified using the order by clause inside the row_number() function.
so I wrote this:
DECLARE #T TABLE (col1 nvarchar(50));
insert into #T VALUES ('A'),('B'),('C'),('D'),('E')
select I1.col1 Instance_One_Col, I2.col1 Instance_Two_Col from (
select col1,row_number() over (order by col1) as row_num
FROM #T
) AS I1
left join (
select col1,row_number() over (order by col1) as row_num
FROM #T
) AS I2 on I1.row_num = I2.row_num - 1
after that I can compare each row to the next one as I need