Fetching records from multiple tables logically with SQLServer - sql

I am having a problem with fetching the records.
Finding it too difficult to get tis but though I am trying.
Please help me regarding this::
Actually My requirement is to get that records from table1 whose sender and reciever userid =5 and to that corresponding records if the pkId of the selected result exists in
table2 as fkid and have to check userId again in table2 with Isdeleted=false
I want to get records from table1 only where sender=5 or receiver=5
and then I need to check the pkId of table1 if it exists in
table2 as fkId then idDeleted should be false but
while checking from table2, I am having a condition to search only where
table2.userid =5
I have tried this but not working
select distinct pkId , Message, data from table1
left outer join table2 on
table2.fkId =table1.pkMessageId
where ((table1.sender ='5' or table1.receiver='5' )
or table2.userid='5') and table2.isDeleted=0
table1
pkId sender receiver Message data date
1 2 5 M1 D1 blah_Blah
2 2 5 M2 D2 blah_Blah
3 5 7 M3 D3 blah_Blah
4 5 2 M4 D4 blah_Blah
5 5 2 M5 D4 blah_Blah
table2
Id fkId userid isDeleted
1 1 5 true
2 1 5 false
3 2 5 false
4 2 2 false
5 3 2 false
6 4 2 true
7 1 2 true
8 2 2 false

Try this:
Select distinct pkId , Message, data from table1
Where (sender = 5 Or receiver = 5) and pkId in
(
Select fkid From table
Where isDeleted=0
)

You should be able to avoid the distinct with an EXISTS statement:
select pkId, Message, data
from table1
where exists ( select 1
from table2
where table2.fkId = table1.pkMessageId
and table2.isDeleted=0
and table2.userid='5' )
and (sender ='5' or receiver='5' )
This is assuming a few things though:
table2.fkId = table1.pkMessageId is the right way of joining the two tables (pkMessageId is lacking in your example data)
You do not want table1.sender ='5' or table1.receiver='5' or table2.userid='5'
If you want OR, OR, OR, this could be what you are looking for:
select pkId, Message, data
from table1
where exists ( select 1
from table2
where table2.fkId = table1.pkMessageId
and table2.isDeleted = 0
and table2.userid='5' )
or sender ='5'
or receiver='5'

I think your issue is you are using the same table for sender and receiver you need to join to the same table twice...
SELECT * FROM Table1
INNER JOIN Table2 Sender
ON Table1.Sender = Sender.userid
INNER JOIN Table2 Receiver
ON Table1.Receiver = Receiver.userid
WHERE
Receiver.isDeleted = 0
AND
Sender.isDeleted = 0
AND
(
Receiver.userid = 5
OR
Sender.userid = 5
)
from your description what you are saying is
SELECT
T1.*
FROM
Table1 T1
INNER JOIN
Table2 T2
ON
T1.pkId = T2.fkId
WHERE
(T1.Sender = 5 OR T1.Receiver = 5)
AND
T2.isDeleted = 0
AND
T2.userid = 5

I will go step by step through your new version of your requirements:
Actually My requirement is to get that records from table1 whose sender and reciever userid =5 and to that corresponding records if the pkId of the selected result exists in table2 as fkid and have to check userId again in table2 with Isdeleted=false
I'll take this step by step.
records from table1 whose sender and reciever userid =5
That is easy, in your example data, there are no such records.
Now, I will assume you mean
records from table1 whose sender OR reciever userid =5
So that leads to a first part of our query:
SELECT *
FROM Table1 t1
WHERE t1.sender = 5
OR t1.receiver = 5
Then, we go further:
and to that corresponding records if the pkId of the selected result exists in table2 as fkid
So, we LEFT JOIN table 2 on matching keys:
SELECT *
FROM Table1 t1
LEFT JOIN Table2 t2 ON t1.pkID = t2.fkId
WHERE t1.sender = 5
OR t1.receiver = 5
Almost there:
and have to check userId again in table2 with Isdeleted=false
I am assuming you want to only add the extra data from table2 if this condition is met, but is the condition is not met, you still want the data from table1. To acheive this, I will put this condition in the JOIN condition, rather than in th eWHERE clause. In the where clause, if the condition is not met, the whole record will be removed, not just the data from table2.
SELECT *
FROM Table1 t1
LEFT JOIN Table2 t2 ON t1.pkID = t2.fkId
AND t2.IsDeleted = 0
WHERE t1.sender = 5
OR t1.receiver = 5
Now, this looks a lot like what you already had created, but I would not know why it would not give you the desired result. So if this does not give you the desired or expected result, please tell us what is going wrong :)

--Try Like This..
SELECT * FROM Table1
Where ( Sender = 5
OR Reciever = 5 )
AND PKID in ( Select FKID From Table2 Where IsDeleted = 0)
-- It would be easy if u can provide the table structures also...

Related

Count when value is in a column in another table

I have two tables
id
val
1
a
1
b
1
c
2
d
2
e
3
f
and
id
1
2
What I want is a count of the number of times an ID appears from the first table ONLY IF if it exists in the second table. How can I do this?
Example output:
id
count
1
3
2
2
3
0
Would you like to show ids that do not exist in the first table?
I made it show according to the ids that exist in the first table, if you want it to show up please comment below
select tb7.id, COUNT(tb6.id) as count
from Table_6 tb6 inner join Table_7 tb7 on tb6.id = tb7.id
group by tb7.id
You can use left outer join and count as follows:
Select t1.id, count(t2.id) as cnt
From table1 t1 left join
table2 t2
on t1.id = t2.id
Group by t1.id;

How to in insert new rows from one table to another based on date?

I am having two tables (table1 and table2). I have columns Date, A, B, C in table1 and columns Date, D, E in table2. I need to transfer column D and E from table2 to table1 based on Date in both the tables.
I tried below code but getting 'multi-part identifier "table1.Date" could not be bound.' error
INSERT INTO table1
SELECT D,E FROM table2
WHERE table2.Date = table1.Date
Table1 :
Date A B C
1945-01-01 1 2 3
1945-02-01 1 2 4
1945-03-01 5 6 7
Table2 :
Date D E
1945-02-01 8 2
1945-03-01 5 6
Expected output:
Table1 :
Date A B C D E
1945-01-01 1 2 3 Null Null
1945-02-01 1 2 4 8 2
1945-03-01 5 6 7 5 6
First you have to add those columns to Table1. Then you need to update the existing rows. Something like this should work.
alter table Table1
add D int
alter table Table1
add E int
GO
update t
set D = t2.D
, E = t2.E
from Table2 t2
left join Table1 t on t.Date = t2.Date
You are rather asking of how to JOIN tables, because you can not add columns with insert statement.
Having said that, you are looking for LEFT JOIN (well, if table on the left side of operator is Table1), try this:
SELECT * FROM Table1 T1
LEFT JOIN Table2 T2 ON T1.[Date] = T2.[Date]
If you want to have this as "table" and use it without JOINs, then I recommend you getting familiar with views: CREATE VIEW (Transact-SQL)

Querying two tables to filter data using select case

I have two tables
Table 1 looks like this
ID Repeats
-----------
A 1
A 1
A 0
B 2
B 2
C 2
D 1
Table 2 looks like this
ID values
-----------
A 100
B 200
C 100
D 300
Using a view I need a result like this
ID values Repeats
-------------------
A 100 NA
B 200 2
C 100 2
D 300 1
that means, I want unique ID, its values and Repeats. Repeats value should display NA when there are multiple values against single ID and it should display the Repeats value in case there is single value for repeats.
Initially I needed to display the max value of repeats so I tried the following view
ALTER VIEW [dbo].[BookingView1]
AS
SELECT bv.*, bd2.Repeats FROM Table1 bv
JOIN
(
SELECT distinct bd.id, bd.Repeats FROM table2 bd
JOIN
(
SELECT Id, MAX(Repeats) AS MaxRepeatCount
FROM table2
GROUP BY Id
) bd1
ON bd.Id = bd1.Id
AND bd.Repeats = bd1.MaxRepeatCount
) bd2
ON bv.Id = bd2.Id;
and this returns the correct result but when trying to implement the CASE it fails to return unique ID results. Please help!!
One method uses outer apply:
select t2.*, t1.repeats
from table2 t2 outer apply
(select (case when max(repeats) = min(repeats) then max(repeats)
else 'NA'
end) as repeats
from table1 t1
where t1.id = t2.id
) t1;
Two notes:
This assumes that repeats is a string. If it is a number, you need to cast it to a string.
repeats is not null.
For the sake of completeness, I'm including another approach that will work if repeats is NULL. However, Gordon's answer has a much simpler query plan and should be preferred.
Option 1 (Works with NULLs):
SELECT
t1.ID, t2.[Values],
CASE
WHEN COUNT(*) > 1 THEN 'NA'
ELSE CAST(MAX(Repeats) AS VARCHAR(2))
END Repeats
FROM (
SELECT DISTINCT t1.ID, t1.Repeats
FROM #table1 t1
) t1
LEFT OUTER JOIN #table2 t2
ON t1.ID = t2.ID
GROUP BY t1.ID, t2.[Values]
Option 2 (does not contain explicit subqueries, but does not work with NULLs):
SELECT DISTINCT
t1.ID,
t2.[Values],
CASE
WHEN COUNT(t1.Repeats) OVER (PARTITION BY COUNT(DISTINCT t1.Repeats), t1.ID) > 1 THEN 'NA'
ELSE CAST(t1.Repeats AS VARCHAR(2))
END Repeats
FROM #table1 t1
LEFT OUTER JOIN #table2 t2
ON t1.ID = t2.ID
GROUP BY t1.ID, t2.[Values], t1.Repeats
NOTE:
This may not give desired results if table2 has different values for the same ID.

After Table Joining, need specific row value based on another Row with same ID

I have 2 tables as follows:
Table 1:
ID FName
1 Basics
2 Machine1
3 master
4 Machine2
15 Machine3
16 Machine16
Table 2:
ParentID Name InitialValue
1 Active 1
2 MachineName Entrylevel
2 Active 1
3 Active 1
4 MachineName Midlevellevel
4 Active 1
15 MachineName Endlevel
15 Active 1
16 MachineName Miscellenious
16 Active 0
Here, ID of Table 1 is referred as Parent ID at Table 2. I want "Initial Value" of Table 2 for MachineName Rows (of Table 2) provided "InitialValue" of Table 2 for Active Rows (of Table 2) are 1
Result should be like
ID InitialValue
2 Entrylevel
4 Midlevellevel
15 Endlevel
You could join the second table twice, once for MachineName, and once for Active:
SELECT t.ID, machine.InitialValue
FROM table1 t
INNER JOIN table2 machine
ON t.ID = machine.ParentId
AND machine.Name = 'MachineName'
INNER JOIN table2 active
ON t.ID = active.ParentId
AND active.Name = 'Active'
AND active.InitialValue = 1;
About Joins
The JOIN syntax allows you to link records to the previous table in your FROM list, most of the time via a relationship of foreign key - primary key. In a distant past, we used to do that with a WHERE condition, but that really is outdated syntax.
In the above query, that relationship of primary key - foreign key is expressed with t.ID = machine.ParentId in the first case. Note the alias that was defined for table2, so we can refer to it with machine.
Some extra condition(s) are added to the join condition, such as machine.Name = 'MachineName'. Those could just as well have been placed in a WHERE clause, but I like it this way.
Then the same table is joined again, this time with another alias. This time it filters the "Active" 1 records. Note that if the ID in table1 does not have a matching record with those conditions, that parent record will be excluded from the results.
So now we have the table1 records with a matching "MachineName" record and are sure there is an "Active" 1 record for it as well. This is what needs to be output.
Not sure if this is standard SQL but it should work using MySQL.
select T1.ID, T2.InitialValue
from Table1 T1 inner join Table2 T2 on T1.ID = T2.ParentId
where
T2.Name <> 'Active'
and exists (
select * from Table2 T3 where T3.ParentId = T1.ID and T3.Name = 'Active' and T3.InitialValue = 1
)
SELECT t1.ID, t2.InitialValue
FROM table1 t1 join table2 t2 on t1.ID=t2.ParentID
WHERE t2.name LIKE 'MachineName'AND t1.ID= ANY(SELECT t22.ParentID
FROM table2 t22
WHERE t22.InitialValue=1)
I think this should work
//slightly changed the condition in WHERE clausule (t2.parentID changed to t1.ID)

Search Row not exist in another table

Can anyone help me to write the query for below condition.
Table 1
ID Key
1 A
2 A
4 C
5 D
6 A
Table 2
ID Key
2 B
3 B
5 D
6 A
These are the two tables
I want a query in which the ID, which is not exist in Table1 corresponding to Table2, where deleted from table.
Example: ID = 1 row was completely deleted from Table1, and in which key are not match were also deleted
Example: ID = 2, exists in both tables but key are not same so the complete row also delete from Table1 not in Table2, I need a single query which is applicable to both condition
Thanks in advance
SELECT id, [Key]
FROM table1
EXCEPT
SELECT id, [Key]
FROM table2
You can try to check if exists in following:
DELETE FROM Table1
WHERE NOT EXISTS (
SELECT 1
FROM Table2 t2
WHERE Table1.Id = t2.Id
)
OR EXISTS (
SELECT 1
FROM Table2 t2
WHERE Table1.Id = t2.Id AND Table1.[Key] <> t2.[Key]
)
OUTPUT
ID Key
5 D
6 A