missing rows, how to select values - sql

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

Related

How to get all non matching rows from both tables in one query?

I have two tables with similar columns and I would like to know the difference between these tables. So if all values (column-wise) of the row exists in both table it is fine (I do not want to see this), while I want to see all rows that.
I have tried this:
select m.*, t.*
from test.test1 m
full outer join test.test2 t
on row(m) = row(t)
where m.date = '2022-11-01'
but I am getting all rows only from the first table. Note. I want only one query (no subqueries)
You need to add the null check for your key columns in the where statement:
select m.*, t.*
from test.test1 m
full outer join test.test2 t
on row(m) = row(t)
where m.KEY is null or t.KEY is null and m.date = '2022-11-01'
You can use the EXCEPT/EXCEPT ALL set operators to compare tables with the column layout (data-types and order of columns (if using SELECT *) must match).
SELECT 'IN TEST1 but not in TEST2' as SRC, EA.*
FROM (
SELECT *
FROM test.test1 m
where m.date='2022-11-01'
EXCEPT ALL
SELECT *
FROM test.test2
) EA
union all
SELECT 'IN TEST2 but not in TEST1' as SRC, EA.*
FROM (
SELECT *
FROM test.test2
EXCEPT ALL
SELECT *
FROM test.test1 m
where m.date='2022-11-01'
) EA

Finding unique combinations of columns

I'm trying to write a select query but am having trouble, probably because I'm not familiar with SQL Server (usually use MySQL).
Basically what I need to do is find the number of unique combinations of 2 columns, one a Varchar and one a Double.
There are less rows in one than another, so I've been trying to figure out the right way to do this.
Essentially pretend Table.Varchar has in it:
Table.Varchar
--------------
apple
orange
and Table.Float has in it:
Table.Float
--------------
1
2
3.
How could I write a query which returns
QueryResult
-------------
apple1
apple2
apple3
orange1
orange2
orange3
Long day at work and I think I'm just overthinking this what I've tried so far is to concat the two columns and then count but it's not working. Any ideas to better go about this?
Select T1.VarcharField + CAST(T2.FloatField as Varchar(10)) as [Concat]
from Table.Varchar T1
CROSS JOIN Table.Float T2
this way, you are generating the fields
so, then group by and use Count
select T.Concat, count(*) from
(Select T1.VarcharField + CAST(T2.FloatField as Varchar(10)) as [Concat]
from Table.Varchar T1
CROSS JOIN Table.Float T2) T
group by T.Concat order by count(*) asc
If they are in the same table:
SELECT a.Field1, b.Field2
FROM [Table] a
CROSS JOIN [Table] b
or if they are in seperate tables:
SELECT a.Field1, b.Field2
FROM [Table1] a
CROSS JOIN [Table2] b
Keep in mind that the above queries will match ALL records from the first table with ALL records from the second table, creating a cartesian product.
This will eliminate duplicates:
DECLARE #Varchar TABLE(v VARCHAR(32));
DECLARE #Float TABLE(f FLOAT);
INSERT #Varchar SELECT 'apple'
UNION ALL SELECT 'orange'
UNION ALL SELECT 'apple';
INSERT #Float SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3;
SELECT v.v + CONVERT(VARCHAR(12), f.f)
FROM #Varchar AS v
CROSS JOIN #Float AS f
GROUP BY v.v, f.f;
A cross join is a join where each record in one table is combined with each record of the other table. Select the distinct values from the table and join them.
select x.Varchar, y.Float
from (select distinct Varchar from theTable) x
cross join (select distinct Float from theTable) y
To find the number of combinations you don't have to actually return all combinations, just count them.
select
(select count(distinct Varchar) from theTable) *
(select count(distinct Float) from theTable)
Try This
Possible Cominations.
SELECT
DISTINCT T1.VarField+CONVERT(VARCHAR(12),T2.FtField) --Get Unique Combinations
FROM Table1 T1 CROSS JOIN Table2 T2 --From all possible combinations
WHERE T1.VarField IS NOT NULL AND T2.FtField IS NOT NULL --Making code NULL Proof
and to just get the Possible Cominations Count
SELECT Count(DISTINCT T1.VarcharField + CONVERT(VARCHAR(12), T2.FloatField))
FROM Table1 T1
CROSS JOIN Table2 T2
WHERE T1.VarcharField IS NOT NULL AND T2.FloatField IS NOT NULL

Filter Out Rows with Matching Substring

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

mysql - union tables by unique field

I have two tables with the same structure:
id name
1 Merry
2 Mike
and
id name
1 Mike
2 Alis
I need to union second table to first with keeping unique names, so that result is:
id name
1 Merry
2 Mike
3 Alis
Is it possible to do this with MySQL query, without using php script?
This is not a join (set multiplication), this is a union (set addition).
SELECT #r := #r + 1 AS id, name
FROM (
SELECT #r := 0
) vars,
(
SELECT name
FROM table1
UNION
SELECT name
FROM table2
) q
This will select all names from table1 and combine those with all the names from table2 which are not in table1.
(
select *
from table1
)
union
(
select *
from table2 t2
left join table1 t1 on t2.name = t1.name
where t1.id is null
)
Use:
SELECT a.id,
a.name
FROM TABLE_A a
UNION
SELECT b.id,
b.name
FROM TABLE_B b
UNION will remove duplicates.
As commented, it all depends on what your 'id' means, cause in the example, it means nothing.
SELECT DISTINCT(name) FROM t1 JOIN t2 ON something
if you only want the names
SELECT SUM(something), name FROM t1 JOIN t2 ON something GROUP BY name
if you want to do some group by
SELECT DISTINCT(name) FROM t1 JOIN t2 ON t1.id = t2.id
if the id's are the same
SELECT DISTINCT COALESCE(t1.name,t2.name) FROM
mytable t1 LEFT JOIN mytable t2 ON (t1.name=t2.name);
will get you a list of unique names from the 2 tables. If you want them to get new ids (like Alis does in your desired results), that's something else and requires the answers to a couple of questions:
do any of the names need to maintain their previous id. And if they do, which table's id should be preferred?
why do you have 2 tables with the same structure? ie what are you trying to accomplish when you generate the unique name list?

SQL Select Distinct with Conditional

Table1 has columns (id, a, b, c, group). There are several rows that have the same group, but id is always unique. I would like to SELECT group,a,b FROM Table1 WHERE the group is distinct. However, I would like the returned data to be from the row with the greatest id for that group.
Thus, if we have the rows
(id=10, a=6, b=40, c=3, group=14)
(id=5, a=21, b=45, c=31, group=230)
(id=4, a=42, b=65, c=2, group=230)
I would like to return these 2 rows:
[group=14, a=6,b=40] and
[group=230, a=21,b=45] (because id=5 > id=4)
Is there a simple SELECT statement to do this?
Try:
select grp, a, b
from table1 where id in
(select max(id) from table1 group by grp)
You can do it using a self join or an inner-select. Here's inner select:
select `group`, a, b from Table1 AS T1
where id=(select max(id) from Table1 AS T2 where T1.`group` = T2.`group`)
And self-join method:
select T1.`group`, T2.a, T2.b from
(select max(id) as id,`group` from Table1 group by `group`) T1
join Table1 as T2 on T1.id=T2.id
2 selects, your inner select gets:
SELECT MAX(id) FROM YourTable GROUP BY [GROUP]
Your outer select joins to this table.
Think about it logically, the inner select gets a sub set of the data you need.
The outer select inner joins to this subset and can get further data.
SELECT [group], a, b FROM YourTable INNER JOIN
(SELECT MAX(id) FROM YourTable GROUP BY [GROUP]) t
ON t.id = YourTable.id
SELECT mi.*
FROM (
SELECT DISTINCT grouper
FROM mytable
) md
JOIN mytable mi
ON mi.id =
(
SELECT id
FROM mytable mo
WHERE mo.grouper = md.grouper
ORDER BY
id DESC
LIMIT 1
)
If your table is MyISAM or id is not a PRIMARY KEY, then make sure you have a composite index on (grouper, id).
If your table is InnoDB and id is a PRIMARY KEY, then a simple index on grouper will suffice (id, being a PRIMARY KEY, will be implictly included).
This will use an INDEX FOR GROUP-BY to build the list of distinct groupers, and for each grouper it will use the index access to find the maximal id.
Don't know how to do it in mysql. But the following code will work for MsSQL...
SELECT Y.* FROM
(
SELECT DISTINCT [group], MAX(id) ID
FROM Table1
GROUP BY [group]
) X
INNER JOIN Table1 Y ON X.ID=Table1.ID