How to use BETWEEN in a reference table - sql-server

I was just wondering on how create a query that in such a way it will check if the column is in between in a reference table.
such as
SELECT *
FROM Table1 WHERE Column1 BETWEEN ( SELECT Column1 , Column2 FROM TABLE2 )
I just don't know how to implement it in a correct way.
Thank you.

If you can have overlapping ranges in Table2, and all you want are (unique) Table1 records that are in any range in Table2, then this query will do it.
SELECT *
FROM Table1
WHERE EXISTS (
SELECT *
FROM Table2
Where Table1.Column1 BETWEEN Table2.Column1 and Table2.Column2)
You can also solve this using JOINs, if the ranges in Table2 are not overlapping, otherwise you will need to use either DISTINCT or ROW_NUMBER() to pare them down to unique Table1 records.

Try This....
SELECT *
FROM Table1 as t1
INNER JOIN Table2 t2 ON t1.Column1 BETWEEN t2.Column1 AND t2.Column2

this works
SELECT * FROM table1 as t1,table2 as t2
WHERE t1.Column1 BETWEEN t2.Column1 AND t2.Column2.

Related

What happens if the sub-query on an IN operator fails?

I have a T-SQL query where I am using the IN operator to find all records where the GUID is in the result of the subquery. However, I recently made changes to the schema so that Table6 does not have a GUID field and now has an AlternateID field. So the subquery for the IN operator fails if you run it. However, if I execute the query as a whole, it always returns all records in TableGUIDResolving table. It's almost as if the IN operator is returning TRUE for all records because the subquery is failing.
I have tried fixing the subquery, and it executes as expected when I do this.
Can someone help me explain this? Is this behavior intentional?
SELECT ID
FROM TableGUIDResolving
WHERE GUID IN (SELECT AlternateID AS GUID FROM Table1
UNION
SELECT GUID FROM Table2
UNION
SELECT GUID FROM Table3
UNION
SELECT GUID FROM Table4
UNION
SELECT GUID FROM Table5
UNION
SELECT GUID FROM Table6)
Yup. That is what happens when you use subqueries without qualified column names. You think you are saying:
select table6.GUID from table6
but this doesn't exist, so the scoping rules in SQL change it to:
select TableGUIDResolving.GUID from table6
I would recommend that you change your logic to a series of NOT EXISTS:
SELECT ID
FROM TableGUIDResolving tgr WHERE GUID IN (
WHERE EXISTS (SELECT 1 FROM Table1 t1 WHERE t1.AlternateID = tgr.GUID) OR
EXISTS (SELECT 1 FROM Table2 t2 WHERE t2.GUID = tgr.GUID) OR
EXISTS (SELECT 1 FROM Table3 t3 WHERE t3.GUID = tgr.GUID) OR
EXISTS (SELECT 1 FROM Table4 t4 WHERE t4.GUID = tgr.GUID) OR
EXISTS (SELECT 1 FROM Table4 t5 WHERE t5.GUID = tgr.GUID) OR
EXISTS (SELECT 1 FROM Table4 t6 WHERE t6.GUID = tgr.GUID)
If you have an index on GUID/AlternateID in each of the tables, then this should have much better performance.

Implement Bitwise OR instead of multiple In clause in sql query

I have a query which uses IN clause (can use EXISTS also) for multiple columns which are filtered using OR Clause inside WHERE Clause. Is there any better approach to write this query.
SELECT columndata FROM TABLE1
WHERE column1key in (select columnkey from #temptable1)
OR column2key in (select columnkey from #temptable2)
OR column3key IN (SELECT columnkey FROM #temptable3)
You can go for 'LEFT JOIN' as shown below
SELECT columndata
FROM TABLE1 tab1
LEFT JOIN #temptable1 t1 on tab1.column1key = t1.columnkey
LEFT JOIN #temptable2 t2 on tab1.column2key = t2.columnkey
LEFT JOIN #temptable3 t3 on tab1.column3key = t3.columnkey
You may get better performance by this, which breaks down the SELECT into separate queries with a de-duplication later.
SELECT columndata FROM TABLE1
WHERE column1key in (select columnkey from #temptable1)
UNION
SELECT columndata FROM TABLE1
WHERE column2key in (select columnkey from #temptable2)
UNION
SELECT columndata FROM TABLE1
WHERE column3key IN (SELECT columnkey FROM #temptable3)
But you would really have to try it
With no or bad indexes, you still have to scan then same amount of data. With good indexes, this may work better...
As a side note, EXISTS and IN will give the same plan here

Find missing values on the same column of two tables

Suppose you have two tables in a SQL Server database with the same schema for both tables. I want to compare a single column on both tables and find the values that are missing in table1 but are in table2. I've been doing this manually in Excel with a macro after I've gotten a distinct list in each query, but it would be less work if I had a query. How can I find the missing records via T-SQL? I'd like to do this for the following data types: datetime, nvarchar & bigint.
SELECT DISTINCT [dbo].[table1].[column1]
FROM [dbo].[table1]
ORDER BY [dbo].[table1].[column1] DESC
SELECT DISTINCT [dbo].[table2].[column1]
FROM [dbo].[table2]
ORDER BY [dbo].[table2].[column1] DESC
There are several ways you can do this...
LEFT JOIN:
SELECT DISTINCT t2.column1
FROM dbo.table2 t2
LEFT JOIN dbo.table1 t1
ON t2.Column1 = t1.Column1
WHERE t1.Column1 IS NULL
NOT EXISTS:
SELECT DISTINCT t2.column1
FROM dbo.table2 t2
WHERE NOT EXISTS (
SELECT 1
FROM dbo.table1 t1
WHERE t1.column1 = t2.column1
)
NOT IN:
SELECT DISTINCT t2.column1
FROM dbo.table2 t2
WHERE t2.column1 NOT IN (
SELECT t1.column1
FROM dbo.table1 t1
)
There are some slight variations in the behavior and efficiency of these approaches... based mostly on the presence of NULL values in columns, so try each approach to find the most efficient one that gives the results you expect.
SELECT DISTINCT [dbo].[table2].[column1]
FROM [dbo].[table2]
except
SELECT DISTINCT [dbo].[table1].[column1]
FROM [dbo].[table1]
All the values of column1 in Table2 that are not present in column1 of Table1
basically, you can use LEFT JOIN.
TableB is set as the main table in this case. By joining it with TableA using LEFT JOIN, the the records that have no match on TableA a will still be in the result list but their values are NULL. So to filter out non matching records, add a filtering condition which only select records with NULL value on tableA.
SELECT b.*
FROM tableB b
LEFT JOIN tableA a
ON a.column1 = b.column1
WHERE a.column1 IS NULL
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
SQL Server 2005 onwards you could use Except
SELECT DISTINCT [dbo].[table2].[column1]
FROM [dbo].[table2]
Except
SELECT DISTINCT [dbo].[table1].[column1]
FROM [dbo].[table1]

The effect of a select with multiple tables in FROM is the same as INNER JOIN but what is the ON clause then?

I have a query like this:
SELECT
*
FROM
table1,
table2
I know this is somewhat equivalent to:
SELECT
*
FROM
table1
INNER JOIN
table2
ON ???
However, what would be the resulting ON clause for the join?
Update
After some testing in SSMS here are my findings
SELECT * FROM table1,table2
gives the same execution plan and the same records as
SELECT * FROM table1 INNER JOIN table2 ON 1=1
and the same thing for
SELECT * FROM table1 CROSS JOIN table2
the column that defines their relationship.
SELECT *
FROM table1
INNER JOIN table2
ON table1.ID = table2.ID
actually the query you have showed is not equal. The first one produces cartesian product of all the records on both table or in other words CROSS JOIN.
SELECT
*
FROM
table1,
table2
is equivalent to:
SELECT
*
FROM
table1
CROSS JOIN
table2
there is no ON statement with a CROSS JOIN. If you need to filter a CROSS JOIN, put it in the WHERE clause.
WHERE table1.DateCreated <= table2.DateModified
After some testing in SSMS here are my findings
SELECT * FROM table1,table2
gives the same execution plan and the same records as
SELECT * FROM table1 INNER JOIN table2 ON 1=1
and the same thing for
SELECT * FROM table1 CROSS JOIN table2

Updating column with value from other table, can't use distinct function

My original data is in Table2. I created Table1 from scratch. I populated Column A like this:
INSERT INTO Table1("item")
SELECT DISTINCT(Table2."item")
FROM Table2
I populated Table1.Totals (Column B) like this:
UPDATE Table1
SET totals = t2.q
FROM Table1 INNER JOIN
(
SELECT t2."item"
, SUM(t2.quantity) AS q
FROM t2
GROUP BY t2."item"
) AS t2
ON Table1."item" = t2."item"
How can I populate Table1."date"? My UPDATE above doesn't work here because I can't use an aggregate function on a date. I was able to get the results I wanted using the following code in a separate query:
SELECT DISTINCT Table1."item"
, Table2."date"
FROM Table1 INNER JOIN Table2
ON Table1."item" = Table2."item"
ORDER BY Table1."item"
But how do I use the results of this query to SET the value of the column? I'm using SQL Server 2008.
If you can't do the insert all over again, as #Lamak suggested, then you could perform an UPDATE this way:
UPDATE t1
SET t1.Date = s.Date
FROM Table1 AS t1
INNER JOIN
(
SELECT Item, [Date] = MAX([Date]) -- or MIN()
FROM Table2
GROUP BY Item
) AS s
ON t1.Item = s.Item;
For SQL Server you coul've use a single INSERT statement:
INSERT INTO Table1(Item, Totals, [Date])
SELECT Item, SUM(Quantity), MIN([Date]) -- It could be MAX([Date])
FROM Table2
GROUP BY Item
The easiest way is to use a simple CTAS (create table as select):
select item as item, SUM(quantity) as Q, MIN(date) as d into table2
from table1
group by item
Instead of creating a table, you could create a view, using a select statement like in #Lamak's answer. That way you wouldn't have to update the new row set each time the Table2 updates.

Resources