I have a table as such:
|testNr |date |
|1 | 2014-01-01 |
|2 | 2014-01-03 |
|3 | 2014-01-03 |
And another one like:
|finalID | testNr | from_date |to_date
|1 | 1 | 2013-12-01 |2013-12-20
|2 | 1 | 2013-12-25 |2014-01-05
|3 | 2 | 2014-01-01 |2014-01-05
I want to lookup the finalID from the second table and join it with the first. It is imporant that the date in the first column is between the date range in the second column.
I would like to end up with:
|testNr |date | finalID
|1 | 2014-01-01 | 2
|2 | 2014-01-03 | 3
|3 | 2014-01-03 | NULL
I am using SQL server. Any ideas on how to approach this?
I think this is what you want
select t1.testNr, t1.date, t2.finalID
from table1 t1 left join table2 t2
on t1.testNr=t2.testNr and t1.date between t2.from_date and t2.to_date
fiddle
Use the following
SELECT t1.*, t2.finalID
FROM table1 t1
LEFT JOIN table2 t2 on t1.testNR=t2.testNR and t1.[date] between t2.from_date and t2.to_date
SQLFIddle
SELECT T1.*,T2.FINALID FROM TABLE1 T1
LEFT JOIN TABLE2 T2 ON T1.TESTNR=T2.TESTNR
AND T1.DATE BETWEEN T2.FROM_DATE AND T2.TO_DATE
Related
I am trying to export an SQL query to Excel, and I need this behaviour but I can't find in anywhere.
This is what I currently have:
SELECT t1.c1, t2.c2
FROM table1 t1
INNER JOIN table2 t2 ON t1.id = t2.id;
|c1| c2 |
----------------
|a | sometext1 |
|a | sometext2 |
|a | sometext3 |
|a | sometext4 |
|b | sometext5 |
|b | sometext6 |
|b | sometext7 |
I want to show the results like this:
|c1| c2 |
|a | sometext1 |
| | sometext2 |
| | sometext3 |
| | sometext4 |
|b | sometext5 |
| | sometext6 |
| | sometext7 |
I want to show only the first item in each group, and hide the rest so it's not shown in Excel.
I am using SQL Server.
You should really do this type of processing in the application, not the database. Why? Because result sets represent unordered sets. Relying on the ordering to understand data makes the results brittle.
But you can. One method is:
select (case when seqnum = 1 then c1 end) as c1, c2
from (select, t.*,
row_number() over (partition by c1 order by (select null)) as seqnum
from t
) t
order by c1, seqnum;
How can I create a query where I can update the table1 column date that I get it on table2?
Here is some example of the tables
Table1:
| stud_id | start_date | birt_date | name | exam_date |
| s001 | 11/19/2018 | 05/20/1999 | john | 10/20/2018 |
| s003 | 01/01/2018 | 05/25/1995 | mike | 10/20/2018 |
| s005 | 12/23/2018 | 02/20/1999 | ed | 10/20/2018 |
| s005 | 12/23/2018 | 02/20/1999 | ed | 10/05/2017 |
Table2:
| stud_id | start_date | exam_date |
| s005 | 01/01/2017 | 10/20/2018 |
| s001 | 01/01/2017 | 10/20/2018 |
| s003 | 01/01/2017 | 10/20/2018 |
Basically I want to change just the start_date of the 3 so s006 will not change.
How can I accomplish that using query? I was thinking using in then select the table but I think its not gonna work.
I need to based on two or more column for the condition of my update so I want to update the table 1 where table1.stud_id = table2.stud_id and table1.exam_date = table2.exam_date
do join and update
update t1
set t1.stardate=t2.startdate,
t1.exam_date=t2.exam_date
from table1 t1 join table2 t2
on t1.stud_id=t2.stud_id
where t2.stud_id='s003' -- if you just need s003 update
You can also use CTE as well to update:
;With cte as
(
select t1.start_date as t1date,t2.start_date as t2date from table1 t1
join table2 t2
on t1.stud_id=t2.stud_id
and t1.exam_date=t2.exam_date
)
update cte set t1date=t2date
You can join the 2 tables:
UPDATE T1
SET Start_Date = T2.Start_Date
FROM Table1 AS T1
INNER JOIN Table2 AS T2
ON T1.stud_id = T2.stud_id
AND T1.exam_date = T2.exam_date
How can I join Table1 on Table2 on opid, only if the table1's date <= table2's date, AND it has no other matches?
Here are some example tables:
Table1
------------+-------+-----+
date | spend | opid|
------------+-------+-----+
2019-07-05 | 5 | 1 |
------------+-------+-----+
2019-07-07 | 4 | 2 |
------------+-------+-----+
2019-07-08 | 6 | 2 |
------------+-------+-----+
Table2
+------------+-------+-----+
| date | users | opid|
+------------+-------+-----+
| 2019-07-06 | 100 | 1 |
+------------+-------+-----+
| 2019-07-08 | 200 | 2 |
+------------+-------+-----+
Expected Table
+------------+-------+-------+
| date | spend | users |
+------------+-------+-------+
| 2019-07-05 | 10 | 100 |
+------------+-------+-------+
| 2019-07-07 | 4 | null |
+------------+-------+-------+
| 2019-07-08 | 6 | 200 |
+------------+-------+-------+
So 7-July doesn't join, because 8-July has already joined.
I think you should try with inner join.
select t1.id, t1.date, t1.spend, t2.id as table2_id, t2.users
from table1 t1 inner join
table2 t2
on t1.date <= t2.date;
This answers the original version of the question.
I think you want a full join:
select t1.id, t1.date, t1.spend, t2.id as table2_id, t2.users
from table1 t1 full join
table2 t2
on t1.date = t2.date;
I have three declared tables:
Table_1 (default) has group number in common with that both sub Table_2 and Table_3
while Table_2 and Table_3 have dates in common
I am having difficulty in joining both sub tables to T1 without losing data after the first join. Instead of NULL, T1 should still have its inital data after T2 is joined.
I tried:
SELECT *
FROM (
SELECT DISTINCT * from #GRP_TABLE as T1
FULL OUTER JOIN
(SELECT * FROM #PASSEDBOOKINGS) AS T2
on T1.T1_GROUP_NUMBER = T2.T2_GROUP_NUMBER
FULL OUTER JOIN
(SELECT * FROM #FAILBOOKINGS)AS T3
ON T3.T3_GROUP_NUMBER = T1.T1_GROUP_NUMBER
and T3.T3_DATE = T2.T2_DATE
)AS JOINS
WHERE JOINS.T3_DATE = CAST(GETDATE() AS DATE)
OR JOINS.T2_DATE = CAST(GETDATE() AS DATE)
#GRP_TABLE AS T1:
|-------|------------------|
|T1_LINE| T1_GROUP_NUMBER |
|-------|------------------|
| A1 | A110 |
|-------|------------------|
| A1 | A120 |
|-------|------------------|
|A1 |A130 |
|-------|------------------|
|A1 |A140 |
|-------|------------------|
|A1 |A150 |
|-------|------------------|
#PASSEDBOOKING AS T2:
|---------------|-----------|----------|
|T2_GROUP_NUMBER| T2_COUNTS | T2_DATE |
|---------------|-----------|----------|
| A110 | 2 |2019-02-25|
|---------------|-----------|----------|
| A120 | 2 |2019-02-25|
|---------------|-----------|----------|
|A130 |2 |2019-02-25|
|---------------|-----------|----------|
#FAILEDBOOKINGS AS T3:
|---------------|-----------|----------|
|T3_GROUP_NUMBER| T3_COUNTS | T3_DATE |
|---------------|-----------|----------|
| A140 | 1 |2019-02-25|
|---------------|-----------|----------|
| A150 | 1 |2019-02-25|
|---------------|-----------|----------|
This results in:
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|T1_LINE| T1_GROUP_NUMBER | T2_GROUP_NUMBER |T2_COUNTS | T3_GROUP_NUMBER |T3_COUNTS | T2_DATE | T3_DATE |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
| NULL | NULL | NULL | NULL | A140 | 1 | NULL | 2019-02-25 |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
| NULL | NULL | NULL | NULL |A150 | 1 | NULL | 2019-02-25 |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|A1 |A110 | A110 | 2 | NULL | NULL | 2019-02-25 | NULL |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|A1 |A120 | A120 | 2 | NULL | NULL | 2019-02-25 | NULL |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|A1 |A130 | A130 | 2 | NULL | NULL | 2019-02-25 | NULL |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
But I am expecting these results:
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|T1_LINE| T1_GROUP_NUMBER | T2_GROUP_NUMBER |T2_COUNTS | T3_GROUP_NUMBER |T3_COUNTS | T2_DATE | T3_DATE |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
| A1 | A140 | NULL | NULL | A140 | 1 | NULL | 2019-02-25 |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
| A1 | A150 | NULL | NULL |A150 | 1 | NULL | 2019-02-25 |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|A1 |A110 | A110 | 2 | NULL | NULL | 2019-02-25 | NULL |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|A1 |A120 | A120 | 2 | NULL | NULL | 2019-02-25 | NULL |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
|A1 |A130 | A130 | 2 | NULL | NULL | 2019-02-25 | NULL |
|-------|------------------|------------------|----------|-----------------|-------------|------------------|------------------|
You can try using COALESCE function - so if the data is not present in one table pick it up from another
Thanks
The reason for the null output
Even if T1 table contains A140 and A150 then the corresponding T2 and T3 dates are not the same actually the dates does not exist from your sample data.
To get the expected out put as you mention you can do the following,
SELECT *
From
#GRP_TABLE as T1
Left JOIN
#PASSEDBOOKINGS AS T2
on T1.T1_GROUP_NUMBER = T2.T2_GROUP_NUMBER
Left JOIN
#FAILBOOKINGS AS T3
ON T3.T3_GROUP_NUMBER = T1.T1_GROUP_NUMBER
WHERE T3.T3_DATE = CAST(GETDATE() AS DATE)
OR T2.T2_DATE = CAST(GETDATE() AS DATE)
Looking to your data seems you need left join
SELECT DISTINCT T1.T1_LINE, T1.T1_GROUP_NUMBER
, T2.T2_GROUP_NUMBER , T2.T2_COUNT
, T3.T3_GROUP_NUMBER, T2.T2_COUNTS, T2.T2_DATE, T3.T3_DATE, T3.T3_COUNT
from #GRP_TABLE T1
LEFT JOIN #PASSEDBOOKING T2 ON T1.T1_GROUP_NUMBER = T2.T2_GROUP_NUMBER
LEFT JOIN #FAILEDBOOKINGS AS T3 ON T1.T1_GROUP_NUMBER = T3.T2_GROUP_NUMBER
FULL OUTER JOIN is very expensive, and I don't see a reason to use it here. You have a primary table in which you always want data returned, and two secondary tables - so a classic case of FROM T1 LEFT JOIN T2, T3...
Consider this instead.
SELECT *
FROM #GRP_TABLE as T1
LEFT JOIN #PASSEDBOOKINGS AS T2
on T1.T1_GROUP_NUMBER = T2.T2_GROUP_NUMBER
and T2.T2_DATE = CAST(GETDATE() AS DATE)
LEFT JOIN #FAILBOOKINGS AS T3
ON T3.T3_GROUP_NUMBER = T1.T1_GROUP_NUMBER
and T3.T3_DATE = T2.T2_DATE
I'm not even sure you have to join date to date, given that both tables are limited to one date anyway.:
SELECT *
FROM #GRP_TABLE as T1
LEFT JOIN #PASSEDBOOKINGS AS T2
on T1.T1_GROUP_NUMBER = T2.T2_GROUP_NUMBER
and T2.T2_DATE = CAST(GETDATE() AS DATE)
LEFT JOIN #FAILBOOKINGS AS T3
ON T3.T3_GROUP_NUMBER = T1.T1_GROUP_NUMBER
and T3.T3_DATE = CAST(GETDATE() AS DATE)
Also consider unioning T2 and T3, might make more sense!
SELECT *
FROM #GRP_TABLE as T1
LEFT JOIN (SELECT 'pass' as type, * FROM #PASSEDBOOKINGS WHERE DATE = CAST(GETDATE() AS DATE
UNION
SELECT 'fail' as type, * FROM #FAILBOOKINGS WHERE DATE = CAST(GETDATE() AS DATE
)
T2 on T2.GROUP_NUMBER = T1.GROUP_NUMBER
I'm trying to figure out how to get the same results using joins, as I would using a not exists condition.
For example, if I had the following two tables:
TABLE 1
--------------
|ID | EXT_ID |
|1 | A |
|2 | B |
|3 | C |
--------------
TABLE 2
-------------------------
|EXT_ID | TB1_ID |PRIMARY|
|A | 1 |1 |
|A | 1 |0 |
|B | 2 |0 |
|B | 2 |0 |
-------------------------
If I'm looking to find the records from table 1 that do not have a primary flag of 1 in table 2, for records that actually have a child in table 2 (to exclude orphans), I could simply write the following (expected to return only ID 2 from table 1):
SELECT TB1.ID FROM Table1 TB1
JOIN Table2
ON Table1.EXT_ID = Table2.EXT_ID
WHERE Table2.Primary = 0
AND NOT EXISTS
(
SELECT * FROM Table2 TB2
WHERE TB1.ID = TB2.TB1_ID
AND TB2.PRIMARY = 1
)
Is there a way to do this with joins? And if so, would there be much efficiency in using the not exists vs. a join?
Thanks in advance!
EDIT: fixed tables.
with x as (select Ext_ID, Tb1_ID, Sum(Primary) as sum_primary
from Table2 group by Ext_ID,Tb1_ID)
SELECT TB1.ID
FROM Table1 TB1 JOIN x
ON Table1.EXT_ID = x.EXT_ID
where x.sum_primary = 0
You can use a CTE for this.
SELECT
TB1.ID, TB1.EXT_ID
FROM
TABLE1 TB1
JOIN TABLE2 TB2 ON TB1.ID = TB2.TB1_ID AND TB1.EXT_ID = Table2.EXT_ID
GROUP BY
TB1.ID, TB1.EXT_ID
HAVING MAX(TB2.[PRIMARY]) = 0