Search for ID in another table from a list of duplicates - sql

I'm trying to get a list from the table Orders where the Column Email_Id from the table Users contain duplicates (rows in Users with duplicated emails).
SELECT
o.[Email], o.[Email_Id], d.intCount
FROM (
SELECT [Email], COUNT(*) as intCount
FROM [Server].[dbo].[Table]
GROUP BY [Email]
HAVING COUNT(*) > 1
) AS d
INNER JOIN [Server].[dbo].[Table] o ON o.[Email] = d.[Email]
So I did try with the following:
SELECT * FROM [Server].[dbo].[Orders]
WHERE [Email_Id] IN/
SELECT
o.[Email], o.[Email_Id], d.intCount
FROM (
SELECT [Email], COUNT(*) as intCount
FROM [Server].[dbo].[Users]
GROUP BY [Email]
HAVING COUNT(*) > 1
) AS d
INNER JOIN [Server].[dbo].[Users] o ON o.[Email] = d.[Email]
)
Which returns a Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
Also tried with:
SELECT [Order_Is], (
SELECT
o.[Email], o.[Email_Id], d.intCount
FROM (
SELECT [Email], COUNT(*) as intCount
FROM [Server].[dbo].[Users]
GROUP BY [Email]
HAVING COUNT(*) > 1
) AS d
INNER JOIN [Server].[dbo].[Users] o ON o.[Email] = d.[Email]
)
as [Email_Id]
FROM [Server].[dbo].[Orders]
With same results.
Any idea of what I'm doing wrong?
Thanks!

SELECT *
FROM [Server].[dbo].[Orders]
JOIN ( SELECT [Email], [Email_Id],
count(*) over (partition by [Email]) as cnt
FROM [Server].[dbo].[Users] ) tt
on tt.[Email_Id] = [Orders].[Email_Id]
and tt.[cnt] > 1

in your WHERE statement subquery, you can only have one field or expression for IN operator, that's what the error says, try this way:
SELECT * FROM [Server].[dbo].[Orders]
WHERE [Email_Id] IN (
SELECT
o.[Email_Id]
FROM (
SELECT [Email], COUNT(*) as intCount
FROM [Server].[dbo].[Users]
GROUP BY [Email]
HAVING COUNT(*) > 1
) AS d
INNER JOIN [Server].[dbo].[Users] o ON o.[Email] = d.[Email]
)

Related

Sort Records comparing sums across multiple tables

In SQL Server, I am wanting to bring back all jobs where
(
SUM(Order.InvoicesReceived) > (SUM(Estimate.GrossValue) + SUM (AdditionalEstimate.GrossValue))
) OR (
SUM(Order.ContractGiven) > (SUM(Estimate.GrossValue) + SUM (AdditionalEstimate.GrossValue))
)
CREATE TABLE Job (id INT, userid INT)
INSERT INTO Job ( id ,userid)VALUES ( 1,1)
INSERT INTO Job ( id ,userid)VALUES ( 2,1)
INSERT INTO Job ( id ,userid)VALUES ( 3,2)
INSERT INTO Job ( id ,userid)VALUES ( 4,2)
INSERT INTO Job ( id ,userid)VALUES ( 5,1)
CREATE TABLE [User] (id INT, UserName NVARCHAR (30))
INSERT INTO [User] ( id ,UserName)VALUES ( 1,'Richard')
INSERT INTO [User] ( id ,UserName)VALUES ( 2,'Jane')
CREATE Table Estimate (id INT, [job] INT, [GrossValue] DECIMAL (18,2))
INSERT INTO Estimate ( id ,[job], GrossValue)VALUES ( 1,3, 100)
INSERT INTO Estimate ( id ,[job], GrossValue)VALUES ( 2,4, 100)
INSERT INTO Estimate ( id ,[job], GrossValue)VALUES ( 3,5, 200)
INSERT INTO Estimate ( id ,[job], GrossValue)VALUES ( 4,5, 200)
CREATE Table AdditionalEstimate (id INT, [job] INT, [GrossValue] DECIMAL (18,2))
INSERT INTO AdditionalEstimate ( id ,[job], GrossValue)VALUES ( 1,1, 100)
INSERT INTO AdditionalEstimate ( id ,[job], GrossValue)VALUES ( 2,2, 100)
INSERT INTO AdditionalEstimate ( id ,[job], GrossValue)VALUES ( 3,5, 100)
INSERT INTO AdditionalEstimate ( id ,[job], GrossValue)VALUES ( 4,5, 100)
CREATE Table [Order] (id INT, [job] INT, ContractGiven DECIMAL (18,2), InvoicesReceived DECIMAL (18,2))
INSERT INTO [Order] ( id ,[job], ContractGiven,InvoicesReceived)VALUES ( 1,1, 50, 0)
INSERT INTO [Order] ( id ,[job], ContractGiven,InvoicesReceived)VALUES ( 2,2, 150, 0)
INSERT INTO [Order] ( id ,[job], ContractGiven,InvoicesReceived)VALUES ( 3,3, 50, 0)
INSERT INTO [Order] ( id ,[job], ContractGiven,InvoicesReceived)VALUES ( 4,4, 150, 0)
INSERT INTO [Order] ( id ,[job], ContractGiven,InvoicesReceived)VALUES ( 5,5, 400, 0)
INSERT INTO [Order] ( id ,[job], ContractGiven,InvoicesReceived)VALUES ( 6,5, 100, 0)
To make it easy to see what results I should get I added the following table and updated the inserts into tables.
JOB Estimate AddEstimate Order
1 Null 100 50
2 Null 100 150
3 100 NULL 50
4 100 NULL 150
5 200 100 500
5 200 100 NA
InvoicedRecieved is ignored for simplicity. Jobs 2,4 Should be returned.
Richard 1, Jane 1
I also need another statement bring back the number of jobs per user that met the above criteria.
Gordon was correct about the need to sum before comparing, due to the Cartesian product. However as his query isn't producing the correct result here is the query which does.
select J.id [Job]
, coalesce(O.InvoicesReceived,0) InvoicesReceived
, coalesce(O.ContractGiven,0) ContractGiven
, coalesce(E.GrossValue,0) + coalesce(A.GrossValue,0) TotalQuoteCost
from Job J
left join (select Job, SUM(O.InvoicesReceived) InvoicesReceived, SUM(O.ContractGiven) ContractGiven from [Order] O group by Job) O on O.Job = J.id
left join (select Job, SUM(E.GrossValue) GrossValue from Estimate E group by Job) E on E.Job = J.id
left join (select Job, SUM(A.GrossValue) GrossValue from AdditionalEstimate A group by Job) A on A.Job = J.id
where (
coalesce(O.InvoicesReceived,0) > (coalesce(E.GrossValue,0) + coalesce(A.GrossValue,0))
) OR (
coalesce(O.ContractGiven,0) > (coalesce(E.GrossValue,0) + coalesce(A.GrossValue,0))
)
select [User Name], count(*)
from (
select U.UserName [User Name], J.id
, coalesce(O.InvoicesReceived,0) InvoicesReceived
, coalesce(O.ContractGiven,0) ContractGiven
, coalesce(E.GrossValue,0) + coalesce(A.GrossValue,0) TotalQuoteCost
from Job J
inner join [User] U on U.id = J.UserId
left join (select Job, SUM(O.InvoicesReceived) InvoicesReceived, SUM(O.ContractGiven) ContractGiven from [Order] O group by Job) O on O.Job = J.id
left join (select Job, SUM(E.GrossValue) GrossValue from Estimate E group by Job) E on E.Job = J.id
left join (select Job, SUM(A.GrossValue) GrossValue from AdditionalEstimate A group by Job) A on A.Job = J.id
where (
coalesce(O.InvoicesReceived,0) > (coalesce(E.GrossValue,0) + coalesce(A.GrossValue,0))
) OR (
coalesce(O.ContractGiven,0) > (coalesce(E.GrossValue,0) + coalesce(A.GrossValue,0))
)
) x
group by [User Name]
DB Fiddle
You need to aggregate before you join:
select U.UserName, count(*)
from [User] U join
Job j
on u.id = j.userid left join
(select o.job, sum(O.InvoicesReceived) as InvoicesReceived,
sum(o.ContractGiven) as ContractGiven
from [Order] O
group by o.job
) o
on o.Job = j.id left join
(select e.job, sum(e.GrossValue) as GrossValue
from estimate e
group by e.job
) e
on e.Job = j.id left join
(select ae.job, sum(ae.GrossValue) as GrossValue
from AdditionalEstimate ae
group by ae.job
) ae
on ae.Job = j.id
group by U.UserName
having coalesce(sum(o.InvoicesReceived), 0) > coalesce(sum(e.GrossValue), 0) + coalesce(sum(ae.GrossValue), 0) or
coalesce(sum(o.ContractGiven), 0) > coalesce(sum(e.GrossValue), 0) + coalesce(sum(ae.GrossValue), 0);
Otherwise, the joins will produce a Cartesian product and the sum()s will be off.
Here is a db<>fiddle.
If you want the jobs that meet these conditions:
select U.UserName, j.id
from [User] U join
Job j
on u.id = j.userid left join
(select o.job, sum(O.InvoicesReceived) as InvoicesReceived,
sum(o.ContractGiven) as ContractGiven
from [Order] O
group by o.job
) o
on o.Job = j.id left join
(select e.job, sum(e.GrossValue) as GrossValue
from estimate e
group by e.job
) e
on e.Job = j.id left join
(select ae.job, sum(ae.GrossValue) as GrossValue
from AdditionalEstimate ae
group by ae.job
) ae
on ae.Job = j.id
where coalesce(o.InvoicesReceived, 0) > coalesce(e.GrossValue, 0) + coalesce(ae.GrossValue, 0) or
coalesce(o.ContractGiven, 0) > coalesce(e.GrossValue, 0) + coalesce(ae.GrossValue, 0);
Which has this db<>fiddle.

Alternative solution for below SQL Query ,TableMasterID NOT IN take so much time

Need alternative solution for below SQL Query ,TableMasterID NOT IN take so much time, If i remove AND TableMasterID NOT IN
(SELECT DISTINCT c.TableMasterID
FROM ComFinalDataBS as C
WHERE C.ComFileID IN
(SELECT Number FROM fn_SplitInt(#ComFileID,','))) text from below query then getting result in 20 seconds otherwise result getting arround 4 minus.
SELECT A.SubTitleId,TableMasterID from SubTitle as A JOIN ComTableMaster as B ON a.SubTitle = b.TblName AND TableMasterID NOT IN (SELECT DISTINCT c.TableMasterID
FROM ComFinalDataBS as C
WHERE C.ComFileID IN
(SELECT Number FROM fn_SplitInt(#ComFileID,','))) AND B.TableMasterID IN
(SELECT DISTINCT d.TableMasterID
FROM ComData as D
WHERE D.ComFileID IN
(SELECT Number FROM fn_SplitInt(#ComFileID,','))) ORDER BY A.MainTitleID
SELECT A.SubTitleId ,
TableMasterID
FROM SubTitle AS A
JOIN ComTableMaster AS B ON A.SubTitle = B.TblName
WHERE NOT EXISTS ( SELECT 1
FROM ComFinalDataBS C
WHERE TableMasterID = C.TableMasterID
AND C.ComFileID IN (
SELECT Number
FROM MEFCampus..fn_SplitInt(#ComFileID, ',') ) )
AND NOT EXISTS ( SELECT 1
FROM ComData D
WHERE TableMasterID = D.TableMasterID
AND D.ComFileID IN (
SELECT Number
FROM MEFCampus..fn_SplitInt(#ComFileID,
',') ) )
AND B.IsDeleted = 0
ORDER BY MainTitleID
Have you tried storing the result from the fn_split_string() into an indexed temp-table first? It should help the Query Optimizer a lot.
SELECT DISTINCT Number
INTO #ComFileID
FROM dbo.fn_SplitInt(#ComFileID,',')
CREATE UNIQUE CLUSTERED INDEX uq0_ComFileID ON #ComFileID (Number) WITH (FILLFACTOR = 100)
SELECT A.SubTitleId,TableMasterID
FROM SubTitle as A
JOIN ComTableMaster as B
ON a.SubTitle = b.TblName
/*
AND B.TableMasterID NOT IN (SELECT DISTINCT c.TableMasterID
FROM ComFinalDataBS as C
JOIN #ComFileID CFI
ON CFI.Number = C.ComFileID )
*/
AND NOT EXISTS ( SELECT *
FROM ComFinalDataBS as C
JOIN #ComFileID CFI
ON CFI.Number = C.ComFileID
WHERE c.TableMasterID = B.TableMasterID )
/*
AND B.TableMasterID IN (SELECT DISTINCT d.TableMasterID
FROM ComData as D
JOIN #ComFileID CFI
ON CFI.Number = D.ComFileID
*/
AND EXISTS ( SELECT *
FROM ComData as D
JOIN #ComFileID CFI
ON CFI.Number = D.ComFileID
WHERE D.TableMasterID = B.TableMasterID )
ORDER BY A.MainTitleID

Increment id value in SQL Server

In my SQL I have this query and I want to increase id with this insert that have
I don't want to use identity(1,1)
INSERT INTO dbo.tbl_waredetails
(wd_id, wd_mt_code, wd_wa_Id, wd_supply, wd_description, wd_status)
SELECT
(SELECT ISNULL(MAX(wd.wd_id), 0) + 1
FROM dbo.tbl_waredetails AS wd),
dbo.tbl_material.mat_code, #id,
dbo.fun_CompRem(mat_code, -1, #user_id) AS supply,
NULL, 0
FROM
tbl_material
INNER JOIN
dbo.tbl_MatUnit ON dbo.tbl_material.mat_MatUnt_Code = dbo.tbl_MatUnit.Matunt_code
INNER JOIN
dbo.tbl_MatGroup ON dbo.tbl_material.mat_MatGrp_Code = dbo.tbl_MatGroup.MatGrp_Code
but it send always 2 as id
Try below query
INSERT INTO dbo.tbl_waredetails
(wd_id, wd_mt_code, wd_wa_Id, wd_supply, wd_description, wd_status)
SELECT
(SELECT ISNULL(MAX(wd.wd_id), 0)
FROM dbo.tbl_waredetails AS wd)+ (row_number() over (order by wd.wd_id)),
dbo.tbl_material.mat_code, #id,
dbo.fun_CompRem(mat_code, -1, #user_id) AS supply,
NULL, 0
FROM
tbl_material
INNER JOIN
dbo.tbl_MatUnit ON dbo.tbl_material.mat_MatUnt_Code = dbo.tbl_MatUnit.Matunt_code
INNER JOIN
dbo.tbl_MatGroup ON dbo.tbl_material.mat_MatGrp_Code = dbo.tbl_MatGroup.MatGrp_Code
with cte as
(select (SELECT isnull(MAX(wd.wd_id),0) FROM dbo.tbl_waredetails ) as iden,dbo.tbl_material.mat_code,#id,
dbo.fun_CompRem(mat_code,-1,#user_id
)as supply,NULL,0
FROM tbl_material INNER JOIN
dbo.tbl_MatUnit ON dbo.tbl_material.mat_MatUnt_Code = dbo.tbl_MatUnit.Matunt_code INNER JOIN
dbo.tbl_MatGroup ON dbo.tbl_material.mat_MatGrp_Code = dbo.tbl_MatGroup.MatGrp_Code
where ROW_NUMBER ( )
OVER ( order by 1 )=1
union all
select c.iden+1,dbo.tbl_material.mat_code,#id,
dbo.fun_CompRem(mat_code,-1,#user_id
)as supply,NULL,0
FROM tbl_material INNER JOIN
dbo.tbl_MatUnit ON dbo.tbl_material.mat_MatUnt_Code = dbo.tbl_MatUnit.Matunt_code INNER JOIN
dbo.tbl_MatGroup ON dbo.tbl_material.mat_MatGrp_Code = dbo.tbl_MatGroup.MatGrp_Code
join cte as d on 1=1
where ROW_NUMBER ( )
OVER ( order by 1 )!=1
)
INSERT INTO dbo.tbl_waredetails
(
wd_id,
wd_mt_code ,
wd_wa_Id ,
wd_supply ,
wd_description ,
wd_status
)
SELECT iden, dbo.tbl_material.mat_code,#id,supply,NULL,0
FROM CTE

SQL join two simple query with count and groupby

hello i have 2 queries and i wanna join together but i don't know how...
SELECT *, count(*) as invii
FROM professionisti JOIN preventivi_invii ON
professionisti.email=preventivi_invii.email
GROUP BY professionisti.email
HAVING invii> 300
SELECT *, count(*) as acquisti
FROM professionisti JOIN contatti_acquistati ON
professionisti.email=contatti_acquistati.email
GROUP BY professionisti.email
HAVING acquisti> 5
the problem for me is multiple count and the group by with same column.
thank u
How about the below query. You would just change the WHERE clause to meet your needs.
SQL Fiddle Example:
SELECT * FROM
(
SELECT p.email,
CASE WHEN ISNULL(m1.invii) THEN 0 ELSE m1.invii END AS invii,
CASE WHEN ISNULL(m2.acquisti) THEN 0 ELSE m2.acquisti END AS acquisti
FROM professionisti p
LEFT JOIN
(
SELECT pp.email, COUNT(*) AS invii
FROM preventivi_invii pp
GROUP BY pp.email
) AS m1 ON p.email = m1.email
LEFT JOIN
(
SELECT c.email, COUNT(*) AS acquisti
FROM contatti_acquistati c
GROUP BY c.email
) AS m2 ON p.email = m2.email
) AS mm
WHERE mm.invii = 0
OR mm.acquisti = 0;
Or you could use:
SELECT * FROM
(
SELECT p.email,
(
SELECT
CASE WHEN ISNULL(COUNT(*)) THEN 0 ELSE COUNT(*) END
FROM preventivi_invii pp
WHERE pp.email = p.email
) AS invii,
(
SELECT
CASE WHEN ISNULL(COUNT(*)) THEN 0 ELSE COUNT(*) END
FROM contatti_acquistati c
WHERE c.email = p.email
) AS acquisti
FROM professionisti p
) AS mm
WHERE mm.invii = 0
OR mm.acquisti = 0

MSSQL Inner Join on Concatenated Column

I'm not a DBA so please don't yell at me. Trying to do an inner join and Group By using a concatenated column. The ON statement is producing a syntax error. I do not have access to the original tables and am trying to normalize this into another table, I know its ugly. Not overly worried about performance, just need to work. Cant use functions either.
SELECT DISTINCT A.[carrier_code],[carrier_name], [carrier_grouping], A.[collector_name], [dataset_loaded], [docnum], [envoy_payer_id], [loc], [market], [master_payor_grouping], [plan_class], [plan_name], A.[resp_ins],A.[resp_ind], A.[resp_payor_grouping], A.[Resp_Plan_Type], A.[rspphone], A.[state], A.[sys],A.[resp_ins]+A.[resp_payor_grouping]+A.[carrier_code]+A.[state]+A.[Collector_Name] as ExtId
FROM [Table1] A
INNER JOIN
(SELECT [resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name] as Extid
FROM [Table1]
WHERE [resp_ind] = 'Insurance'
GROUP BY [resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name]) B
ON A.[resp_ins]+A.[resp_payor_grouping]+A.[carrier_code]+A.[state]+A.[Collector_Name] = B.[resp_ins]+B.[resp_payor_grouping]+B.[carrier_code]+B.[state]+B.[Collector_Name];
My ON and Group By statements are eventually the primary key in new table.
Your alias B hasn't columns as you mentioned. It has just on column Extid.
SELECT DISTINCT A.[carrier_code],[carrier_name], [carrier_grouping], A.[collector_name], [dataset_loaded], [docnum], [envoy_payer_id], [loc], [market], [master_payor_grouping], [plan_class], [plan_name], A.[resp_ins],A.[resp_ind], A.[resp_payor_grouping], A.[Resp_Plan_Type], A.[rspphone], A.[state], A.[sys],A.[resp_ins]+A.[resp_payor_grouping]+A.[carrier_code]+A.[state]+A.[Collector_Name] as ExtId
FROM [Table1] A
INNER JOIN
(SELECT [resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name] as Extid
FROM [Table1]
WHERE [resp_ind] = 'Insurance'
GROUP BY [resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name]) B
ON A.[resp_ins]+A.[resp_payor_grouping]+A.[carrier_code]+A.[state]+A.[Collector_Name] = B.Extid;
Try this, I didn't put all the column in result, you can manage yourself.
select A.*
from
(
select [carrier_code],[carrier_name], [sys],[resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name] as ExtId
FROM [Table1]
) A
inner join
(
select distinct Extid
from
(
SELECT [resp_ins]+[resp_payor_grouping]+[carrier_code]+[state]+[Collector_Name] as ExtId
FROM [Table1]
WHERE [resp_ind] = 'Insurance'
) ins
) B on (A.ExtId = B.ExtId)
You don't need to concatenate the values - you can GROUP BY and JOIN on multiple columns.
SELECT DISTINCT
...
FROM
[Table1] A
INNER JOIN
(
SELECT
[resp_ins],
[resp_payor_grouping],
[carrier_code],
[state],
[Collector_Name]
FROM
[Table1]
WHERE
[resp_ind] = 'Insurance'
GROUP BY
[resp_ins],
[resp_payor_grouping],
[carrier_code],
[state],
[Collector_Name]
) B
ON
(
A.[resp_ins] = B.[resp_ins]
Or
(A.[resp_ins] Is Null And B.[resp_ins] Is Null)
)
And
(
A.[resp_payor_grouping] = B.[resp_payor_grouping]
Or
(A.[resp_payor_grouping] Is Null And B.[resp_payor_grouping] Is Null)
)
And
(
A.[carrier_code] = B.[carrier_code]
Or
(A.[carrier_code] Is Null And B.[carrier_code] Is Null)
)
And
(
A.[state] = B.[state]
Or
(A.[state] Is Null And B.[state] Is Null)
)
And
(
A.[Collector_Name] = B.[Collector_Name]
Or
(A.[Collector_Name] Is Null And B.[Collector_Name] Is Null)
)
;