I have a group of insert statements below. The only difference between them is the Thru_DT. The first insert is for 6/30/2019 date. The second is for 15 days before that date and the third is for 15 days before the second insert's date. How do I generate these dates automatically without having to hard code them?
INSERT INTO table1 (a, b, c)
SELECT t2.a1, Max(t2.b1) Provider, t2.c1
From table2 t2
LEFT JOIN tb t1 On t2.a = t1.a1
WHERE t1.b Is Null And t2.Thru_DT >= '6/30/2019'
And t2.c In (Select CCN From table3)
INSERT INTO table1 (a, b, c)
SELECT t2.a1, Max(t2.b1) Provider, t2.c1
From table2 t2
LEFT JOIN tb t1 On t2.a = t1.a1
WHERE t1.b Is Null And t2.Thru_DT >= '6/15/2019'
And t2.c In (Select CCN From table3)
INSERT INTO table1 (a, b, c)
SELECT t2.a1, Max(t2.b1) Provider, t2.c1
From table2 t2
LEFT JOIN tb t1 On t2.a = t1.a1
WHERE t1.b Is Null And t2.Thru_DT >= '6/1/2019'
And t2.c In (Select CCN From table3)
You can build the dates in a CTE:
;WITH cte_date(thru_DT)
AS
(
SELECT #GivenDate
UNION ALL SELECT DATEADD(DAY,-15,#GivenDate)
UNION ALL SELECT DATEADD(DAY,-30,#GivenDate)
)
INSERT INTO table1 (a, b, c)
SELECT t2.a1, Max(t2.b1) Provider, t2.c1
From table2 t2
INNER JOIN table3 t3
ON t2.c=t3.CCN
INNER JOIN cte_date d
ON t2.Thru_DT >= d.Thru_DT
LEFT JOIN tb t1 On t2.a = t1.a1
WHERE t1.b Is Null
Use a table constructor:
INSERT INTO table1 (a, b, c)
SELECT t2.a1, Max(t2.b1) Provider, t2.c1
FROM table2 t2 LEFT JOIN
tb t1
ON t2.a = t1.a1 CROSS JOIN
(VALUES ('2019-06-30'), ('2019-06-15'), ('2019-06-01')
) v(Thru_DT)
WHERE t1.b Is Null AND
t2.Thru_DT >= v.Thru_DT AND
t2.c IN (SELECT CCN FROM table3);
Related
I am new to sql and have a simple question. I have two tables, t1 and t2, both have same fields A, B, C,D
I want to create a sql that
select
*
from t1
where (t1.A exist in t2.A)
AND (combination (ABC) from t1 not exist in t2)
I am using access 2013
Thank you!
You may try using exists logic:
SELECT t1.*
FROM table1 t1
WHERE
EXISTS (SELECT 1 FROM table2 t2 WHERE t2.A = t1.A) AND
NOT EXISTS (SELECT 1 FROM table2 t2 WHERE t2.B = t1.B AND t2.C = t1.C);
Something like this may work:
SELECT *
FROM t1
WHERE
A in (SELECT A from t2) AND
NOT EXISTS (
SELECT *
FROM t2
WHERE t1.B = t2.B AND
t1.C = t2.C AND
t1.D = t2.D
);
I have a table1 (a,b,c) and table2(a,b,c)
What's the difference between
select * from table1 T1 inner join table2 T2 on
T1.a=T2.a and T1.b = t2.b and T1.c = T2.c
and
select * from table1 T1 inner Join table2 T2 on T1.a = T2.a where
T1.b= T2.b and T1.c = T2.C
Is is the same ? and which one is better?
Thanks
With inner joins there are no difference. It is only when you start using left/right joins, that you will see differences.
For LEFT JOINS, if you had
select *
from table1 T1 LEFT join
table2 T2 on T1.a=T2.a
and T1.b = t2.b
and T1.c = T2.c
It would include all rows fromo table1 and only rows from table2 where fields a,b and c matched.
If you had
select *
from table1 T1 inner Join
table2 T2 on T1.a = T2.a
where T1.b= T2.b
and T1.c = T2.C
This would include rows from table1 and those from table2 where a is equal, and then filter on b and c.
SQL Fiddle DEMO
I always find this visual representation usefull.
SQL SERVER – Introduction to JOINs – Basic of JOINs
For your queries, this doesn't change anything.
And in term of performance, your RDBMS is able to understand that it's the same.
But considering you have more joins, this would change the readability of the query.
Example :
SELECT
*
FROM
table1 T1
INNER JOIN table2 T2
ON T1.a = T2.a
AND T1.b = T2.b
AND T1.c = T2.c
LEFT JOIN table3 T3
ON T3.x = T1.a
AND T3.status = 1
WHERE
T1.a > 100
You can understand faster which condition works with which table in INNER/LEFT JOIN
A and B of table T3 are the same as A and B from T1.
Basically what I need to do is select all the values that aren't on T3.
If there is a line with A,B on T3 I don't wanna show it.
SELECT T1.A, T1.B, T1.C
FROM T1, T2
WHERE T1.X=T2.X
AND NOT EXISTS
(
SELECT T3.A, T3.B
FROM T3
)
Any help?
Thanks
SELECT T1.A, T1.B, T1.C
FROM T1 INNER JOIN T2 ON T1.X=T2.X
WHERE NOT EXISTS
(
SELECT 1 FROM T3
WHERE T3.A = T1.A AND T3.B = T1.B
)
select T1.A,T1.B,T1.C
from T1
inner join T2
on T1.X=T2.X
left join T3 on T1.A=T3.A and T1.B=T3.B
where T3.A is null
You can also do that using subqueries like
SELECT T1.A, T1.B, T1.C
FROM T1, T2
WHERE T1.X=T2.X
AND T1.A NOT IN (SELECT T3.A FROM T3)
AND T2.B Not IN (SELECT T3.B FROM T3)
SELECT T1.A, T1.B, T1.C
FROM T1, T2
WHERE T1.X=T2.X
AND (T1.A, T1.B) NOT IN (SELECT T3.A, T3.B FROM T3 )
I have two tables, tbl and tbl2 I have to join. Columns of tbl are irrelevant. Here is the tructure of tbl2:
CREATE TABLE tbl2 (
a VARCHAR(10)
, b VARCHAR(10)
, c VARCHAR(10)
, d VARCHAR(10)
, e VARCHAR(10)
);
What I need to do is apply the following join:
if there are several rows with the same a, b and c LEFT JOIN them on a, b, c and d.
else if there are several rows with the same a and b and they are not in the set mentioned above LEFT JOIN on a, b and c
else LEFT JOIN remaining rows from tbl2 on a and b.
I have been thinking what is the best way to achieve the following. tbl2 can be modified since it is only used for the purpose of this query.
Do you have any ideas what is the most efficient way of achieving this?
EDIT:
By 'having the same a, b and c' I meant something like this:
SELECT a, b, c FROM tbl2 GROUP BY a, b ,c HAVING COUNT(*) > 1
WITH tab_a AS
(
SELECT t2.a
, t2.b
, t2.c
, t2.d
, t2.e
, CASE WHEN t1.c = t2.c THEN 1 ELSE 0 END +
CASE WHEN t1.d = t2.d THEN 1 ELSE 0 END AS other_two
FROM tbl t1
LEFT JOIN tbl2 t2
ON t1.a = t2.a
AND t1.b = t2.b
)
SELECT a
, b
, c
, d
, e
FROM tab_a
WHERE other_two = (SELECT MAX(other_two) FROM tab_a);
put these three queries in if else condition. If you want them all then UNION these three.
select *
from tbl t1 left outer join tbl2 t2
on (t1.a=t2.a and t1.b=t2.b and t1.c=t2.c and t1.d=t2.d)
where t2.a=t2.b and t2.b=t2.c;
select *
from tbl t1 left outer join tbl2 t2
on (t1.a=t2.a and t1.b=t2.b and t1.c=t2.c )
where t2.a=t2.b and t2.b<>t2.c;
select *
from tbl t1 left outer join tbl2 t2
on (t1.a=t2.a and t1.b=t2.b)
where t2.a<>t2.b and t2.b<>t2.c;
or try this:
select *
from tbl t1 left outer join tbl2 t2
on (
(t1.a=t2.a and t1.b=t2.b and t1.c=t2.c and t1.d=t2.d and t2.a=t2.b and t2.b=t2.c)
or
(t1.a=t2.a and t1.b=t2.b and t1.c=t2.c and t2.a=t2.b and t2.b<>t2.c)
or
(t1.a=t2.a and t1.b=t2.b and t2.a<>t2.b and t2.b<>t2.c) );
I was wondering if there was a way to convert a self subquery to a self join
Here is the self subquery
SELECT a,
b
FROM c AS t1
WHERE ( b IN (SELECT b
FROM c AS t2
WHERE ( t1.b = b )
AND ( t1.e <> e )) )
If you only want to find the duplicates an EXIST would probably be faster:
SELECT a,b FROM c WHERE EXISTS(SELECT NULL FROM c c2 WHERE c2.b=c.b AND c2.e<>c.e)
If you want to join every record with its duplicate but get only one record for each:
select t1.a
, t1.b
, t1.e as t1e
, t2.e as t2e
from c as t1
inner join c as t2
on t1.b = t2.b
and t1.e > t2.e
(note that i've used > instead of <>)
As e is the Primary Key another way of approaching this would be
SELECT a,
b
FROM (SELECT a,
b,
COUNT(*) OVER (PARTITION BY b) AS Cnt
FROM c) T1
WHERE Cnt > 1
SELECT t1.a, t2.b
FROM c as t1
join c as t2 on t1.b=t2.b
WHERE t1.e <> t2.e
select t1.a
, t1.b
from c as t1
join c as t2
on t1.b = t2.b
and t1.e <> t2.e