Find new values in new table - sql-server

I Have Table NEW:
Customer Date Id
1 201401 9
1 201401 1
1 201402 2
2 201404 3
2 201404 4
3 201406 5
4 201408 6
And table OLD:
Customer Date Id
1 201401 1
1 201402 2
2 201404 3
2 201404 4
3 201406 5
4 201408 6
Table NEW has all values from table OLD plus some new ones that are not in table OLD.
I need to find Customer that has same Key (column Customer) and same Date (Date) in both tables (OLD and NEW) and different ID in those tables.
So the SELECT should return in this case only
1 201401 9
I tried simple join :
SELECT *
FROM NEW n
LEFT JOIN OLD o ON n.ID = o.ID
WHERE n.Date = o.Date
AND n.ID <> o.ID
but its obviously wrong because of the condition for the join. But I can't join it on Customer so how can i do it some other way?
Thank you

You could use EXISTS/NOT EXISTS:
SELECT n.*
FROM NEW n
WHERE EXISTS(
SELECT 1 FROM Old o
WHERE n.Customer = o.Customer AND n.Date = o.Date
AND n.ID <> o.ID
)
AND NOT EXISTS(
SELECT 1 FROM Old o
WHERE n.Customer = o.Customer AND n.Date = o.Date
AND n.ID = o.ID
)
Demo

Related

Join two tables based on the first table id

I have two tables like this
table A:
ID NAME
1 TED
2 JIM
3 AJU
4 ANN
Table B :
ID AGE
1 12
2 14
3 15
4 13
5 15
6 13
7 12
8 16
9 14
10 12
And I want output like
ID NAME AGE
1 TED 12
2 JIM 14
3 AJU 15
4 ANN 13
You want to join these two tables and return all common entries present in both tables(sets), joins are done based on some common entity(usually keys), in your case it is the column 'ID' .
An inner join of A and B gives the result of A intersect B, i.e. the inner part of a Venn diagram intersection.
select A.*,B.age
from tablea A
inner join tableb b
on a.id = b.id
Just Do a simple Query and you will get your result
Select A.ID,A.NAME,(Select B.AGE FROM B WHERE B.ID = A.ID)
FROM A
Another way to do that
SELECT A.ID,A.NAME,B.AGE
FROM A JOIN B
ON A.ID = B.ID
just do a simple join
SELECT
A.*
B.Age
FROM TABLEA A
INNER JOIN TABLEB B
ON A.ID = B.ID

when sum two columns in different table the record sum duplicate

table 1 table2
k2 id k1 id
3 1 3 1
3 1 3 1
3 1 3 1
5 2 5 2
6 2 6 2
7 2 7 2
7 2 7 2
7 2 7 2
5 2
output i need is:
id sum k1 sum k1
1 9 9
2 37 32
Here is the query i used:
select table1.id,sum(table1.k1),table2.id,sum(table2.k1) from table1,table2
where table1.id= table2.id
but output i have not right
A simple combination of UNION and GROUP BY will give you desired result. Here you go..
SELECT id,max(SumK1) AS SumK1,max(SumK2) AS SumK2 FROM
(
SELECT ID, sum(k1) AS SumK1, NULL AS SumK2 FROM table1 GROUP BY id
UNION
SELECT ID, NULL AS SumK1, sum(k2) AS SumK2 FROM table2 GROUP BY id
) T
GROUP BY id
This should do the trick:
SELECT
COALESCE(table1_result.id1, table2_result.id2) AS id
, table1_result.sum_k1 AS sum_k1
, table2_result.sum_k2 AS sum_k2
FROM
( SELECT id AS id1, SUM(k1) AS sum_k1 FROM table1 GROUP BY id ) AS table1_result
FULL OUTER JOIN ( SELECT id AS id2, SUM(k2) AS sum_k2 FROM table2 GROUP BY id ) AS table2_result
ON table1_result.id1 = table2_result.id2
The first sub-query in the FROM clause:
SELECT id AS id1, SUM(k1) AS sum_k1 FROM table1 GROUP BY id
will give you a result of
id1 sum_k1
1 9
2 37
And likewise, the second sub-query will give the sum for table 2.
id2 sum_k2
1 9
2 32
The outer query matches the id values from both sub-queries and displays the respective sums from table 1 and table 2 alongside one another.
id sum_k1 sum_k2
1 9 9
2 37 32
I believe table1 has id and k1 column. So, you can do this:
select coalesce(t1.id, t2.id) id,
sum(t1.k1) sum_t1_k1,
sum(t2.k1) sum_t2_k1
from table1 t1 full outer join table2 t2
t1.id = t2.id
group by coalesce(t1.id, t2.id);

How to Select distinct data from three tables?

How can I write a SQL statement to select distinct data from three tables?
There are three tables
1)
Registration
id name contact
123 abc 123456789
2) bookingReg
PkBkID FkRegID ac_no
1 123 QT123
3) products
PkPro FkBkID pro_name Qty price
1 1 abc 2 150
2 1 def 1 400
3 1 ghi 5 500
4 1 abc 2 150
SELECT * FROM Registration as a
JOIN bookingReg as b ON (b.FkRegID = '123')
JOIN products as c ON (c.FkBkID = b.PkBkID )
I want distinct pro_name
Out put is
ac_no qty price
QT123 8 1050
HOw ?
Answer based on my assumption
SELECT pro_name,
ac_no,
SUM(qty) Sumqty,
SUM(price) SumPrice
FROM Registration a
JOIN bookingReg b
ON b.FkRegID = a.id
JOIN products c
ON c.FkBkID = b.PkBkID
GROUP BY pro_name, ac_no
EDIT Remove ac_no from SELECT and GROUP BY if you don't want to see this field in result.
Pls try this
SELECT A.ac_no, SUM(A.Qty) Qty, SUM(A.Price) Price
FROM
(
SELECT DISTINCT B.ac_no, P.Qty, P.Price
FROM Registration R
INNER JOIN bookingReg B ON B.FkRegID = R.id
INNER JOIN products P ON P.FkBkID = B.PkBkID
) A
GROUP BY A.ac_no

select Duplicate Records in sql server

I have two tables tblDoc and tblrev
tblDoc
DocID DocNum
1 Doc-001
2 Doc-002
3 Doc-003
4 Doc-004
5 Doc-005
tblRev
revID DocID ReV
1 2 A
2 2 A
3 1 B
4 3 c
I need to select DocID and revID of the duplicates in tblRev where a duplicate record is known as with the same DocID and Rev.
ex: revID 1,2 is a duplicate
plz help
SELECT revID
FROM TblRev
WHERE Rev IN
(
SELECT ReV
FROM tblRev
GROUP BY Rev, DocId
HAVING COUNT(*) > 1
)
Try the following:
;WITH Duplicates AS
(
SELECT
[DocID]
, [ReV]
, COUNT([revID]) as [Count]
FROM tblRev
GROUP BY
[DocID]
, [ReV]
),
DuplicateRevID AS
(
SELECT
R.[revID]
, R.[DocID]
FROM Duplicates D
INNER JOIN tblRev R ON
D.[DocID] = R.[DocID]
AND D.[ReV] = R.[ReV]
WHERE
D.[Count] > 1
)
SELECT *
FROM DuplicateRevID
Try this
select tr.revID,tr.DocID FROM tblDoc td
Inner Join tblRev tr on td.DocID = tr.DocID
GROUP BY tr.revID,tr.DocID
Having count(td.DocID )> 1

help me in forming an sql query

i have two tables .. one is a master table and other one is an daily report table.
Master table :
machine_id Machinename
1 abc
2 def
3 ghi
4 jkl
ven_fullreportmaster :
entry_date machine_id description_id tot_time shift_id
20110613 1 1 10 1
20110613 2 2 9 2
20110614 1 1 10 1
20110614 1 2 9 2
20110614 3 3 5 3
20110614 2 4 10 1
20110614 2 1 9 2
20110614 2 5 5 3
now, i want to retrieve the data from the daily report table that it should contain all the machine names with tot_time and entry_date..
i have used this query to retrieve the data,
select entry_date,
machinename,
(IsNull(cast(TotalMins / 60 as varchar(24)),'0') + ':' + IsNull(cast(TotalMins % 60 as varchar(24)),'0')) as TotalHrs--, shift_type
from (
select vm.machinename , vfrm.entry_date,
sum(case when vfrm.description_id in ('1','2','3','4','5') then DateDiff(mi, 0, total_time) else '0' end) as TotalMins
--vsm.shift_type
from ven_fullreportmaster vfrm
inner join ven_machinemaster vm on vm.machine_id = vfrm.machine_id
inner join ven_shifttypemaster vsm on vsm.shift_id = vfrm.shift_id
where vfrm.entry_date = '20110614'
-- and vfrm.shift_id in (1,2,3)
group by machinename, vfrm.entry_date --, vsm.shift_type
) as SubQueryALias group by entry_date, machinename,TotalMins --,shift_type
when i run the above query, i am getting details for machine-id 1 , 2,3 alone..
output:
entry_date machineid TotalHrs
2011-06-14 00:00:00.000 1 19:0
2011-06-14 00:00:00.000 2 24:0
2011-06-14 00:00:00.000 3 5:0
i need to get machine_id =4 value as 0 in TotalMins for each shift.. how to resolve it..plz help me ..
expected output:
entry_date machineid TotalHrs
2011-06-14 00:00:00.000 1 19:0
2011-06-14 00:00:00.000 2 24:0
2011-06-14 00:00:00.000 3 5:0
**2011-06-14 00:00:00.000 4 0:0**
thanks and regards
T.Navin
output:
Try using left joins instead of inner joins, that should get machine #3 to appear even though it has no entries in the second table.
You are searching for records with a specific date but there is no entry for 20110614 in your reporting table.
One solution is to add records to your select using a UNION with an initial SUM of'0'.
These fake records will not throw off your existing SUM.
They will show up where there's missing data with '0'.
SQL Statement
SELECT entry_date
, machinename
, (ISNULL(CAST(TotalMins / 60 AS VARCHAR(24)),'0') + ':' + ISNULL(CAST(TotalMins % 60 AS VARCHAR(24)),'0')) AS TotalHrs--, shift_type
FROM (
SELECT vm.machinename
, vfrm.entry_date
, SUM(case when vfrm.description_id in ('1','2','3','4','5') THEN DATEDIFF(mi, 0, total_time) else '0' END) AS TotalMins --vsm.shift_type
FROM ven_fullreportmaster vfrm
INNER JOIN ven_machinemaster vm on vm.machine_id = vfrm.machine_id
INNER JOIN ven_shifttypemaster vsm on vsm.shift_id = vfrm.shift_id
WHERE vfrm.entry_date BETWEEN '20110614' AND '20110615'
GROUP BY
machinename
, vfrm.entry_date --, vsm.shift_type
UNION ALL
SELECT DISTINCT vm.machinename
, vfrm.entry_date
, '0'
FROM ven_machinemaster vm
CROSS APPLY ven_fullreportmaster vfrm
WHERE vfrm.entry_date BETWEEN '20110614' AND '20110615'
) AS SubQueryALias
GROUP BY
entry_date
, machinename
, TotalMins --,shift_type
Instead of:
from ven_fullreportmaster vfrm
inner join ven_machinemaster vm on vm.machine_id = vfrm.machine_id
inner join ven_shifttypemaster vsm on vsm.shift_id = vfrm.shift_id
where vfrm.entry_date = '20110614'
can you try this LEFT JOIN ? Note the moving of the condition from WHERE to the ON clause:
FROM ven_machinemaster vm
LEFT JOIN ven_fullreportmaster vfrm
ON vm.machine_id = vfrm.machine_id
AND vfrm.entry_date = '20110614'
INNER JOIN ven_shifttypemaster vsm
ON vsm.shift_id = vfrm.shift_id
or:
FROM ven_machinemaster vm
LEFT JOIN ven_fullreportmaster vfrm
ON vm.machine_id = vfrm.machine_id
AND vfrm.entry_date = '20110614'
LEFT JOIN ven_shifttypemaster vsm
ON vsm.shift_id = vfrm.shift_id

Resources