Sort Records comparing sums across multiple tables - sql

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.

Related

How to sum columns when table is joined?

Trying to sum from a table that is joined to another (resulting in multiple rows per row of the first table) it is counting the amount for each of the rows in second table.
Tables:
create table t_orders (
oid int,
cartlink nvarchar(3),
ordertotal float,
ordertax float
);
create table t_cart (
cartlink nvarchar(3),
productid int
);
insert into t_orders (oid,cartlink,ordertotal,ordertax) values
(1,'abc',10, 2),
(2,'cdf',9, 1),
(3,'zxc',11, 3)
;
insert into t_cart (cartlink,productid) values
('abc', 123),('abc', 321),('abc', 987),
('cdf', 123),('cdf', 321),('cdf', 987),
('zxc', 123),('zxc', 321),('zxc', 987)
;
Using following values for t_orders table is more accurate to the problem. Using distinct only counts order 2 and 3 once because both of their totals are 9.
insert into t_orders (oid,cartlink,ordertotal,ordertax) values
(1,'abc',10, 2),
(2,'cdf',9, 1),
(3,'zxc',9, 3)
;
Query and result:
SELECT
SUM(t_orders.ordertotal) AS SumOfTotal,
SUM(t_orders.ordertax) AS SumOfTax
FROM
t_orders
JOIN t_cart ON t_orders.cartlink = t_cart.cartlink
;
SumOfTotal
SumOfTax
90
18
What I want :
SumOfTotal
SumOfTax
30
6
I have to join t_orders -> t_cart -> t_products -> t_manufacturer because I'm trying to sum from t_orders WHERE t_manufacturer.type = 'some value'.
Try this
SELECT SUM(DISTINCT t_orders.ordertotal) AS SumOfTotal
, SUM(DISTINCT t_orders.ordertax) AS SumOfTax
FROM t_orders
JOIN t_cart ON t_orders.cartlink = t_cart.cartlink
"… I'm trying to sum from t_orders WHERE t_manufacturer.type = 'some value'."
Using sub-query:
SELECT
SUM(t1.Total) AS SumOfTotal,
SUM(t1.Tax) AS SumOfTax
FROM
(
SELECT
MAX(t_orders.ordertotal) AS Total,
MAX(t_orders.ordertax) AS Tax
FROM t_orders
JOIN t_cart ON t_orders.cartlink = t_cart.cartlink
JOIN t_products ON t_cart.productid = t_products.pid
JOIN t_manufacturer ON t_products.manufacturerid = t_manufacturer.mid
WHERE t_manufacturer.type = 'some value'
GROUP BY t_orders.oid
) AS t1
Or:
SELECT
SUM(t1.Total) AS SumOfTotal,
SUM(t1.Tax) AS SumOfTax
FROM
(
SELECT
MAX(t_orders.ordertotal) AS Total,
MAX(t_orders.ordertax) AS Tax
FROM t_orders
JOIN t_cart ON t_orders.cartlink = t_cart.cartlink
JOIN t_products ON t_cart.productid = t_products.pid
WHERE t_products.manufacturerid IN (
SELECT mid FROM t_manufacturer WHERE type = 'some value'
) AS t2
GROUP BY t_orders.oid
) AS t1

Search for ID in another table from a list of duplicates

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]
)

Querying a column that shows [count] of [max count]

I have 3 tables:
CustomerTypes table
Customers table (has a foreign key CustomerType). A customer can only have one customer type.
CustomersCollection table (contains many customerIds)
The primary SELECT of the query will be on CustomerTypes. I will be selecting two columns: CustomerTypeName and CountInCollection
The CustomerCount column in my query needs to show something like the following:
[Total # of Customers in CustomerType that are in Customer Collection] Of [Total # of Customers in CustomerType]
How can I get the proper customer count of the CustomerType that is part of the collection?
Example:
Customer1, Customer2, and Customer3 are all of CustomerTypeA.
CustomerCollection1 has customers Customer1 and Customer2 in it. The CountInCollection column for the CustomerTypeA record should show '2 of 3'.
Here is how I am able to get each count in separate queries:
-- Total customers in customer collection of customer type
SELECT COUNT(c.Id)
FROM Customer c
INNER JOIN CustomerCollection cc ON c.Id = cc.CustomerId
WHERE cc.CollectionId = 1019 AND c.CustomerTypeId=1000
-- Total customers in customer type
SELECT COUNT(Id) FROM
Customer WHERE CustomerTypeId=1000
Since you are using SQL 2008, I would take advantage of Common Table Expressions, aka CTEs, to assemble the data.
First, we'll need some test data. NOTE: I've thrown in some 'outliers' so that you can see where this kind of logic can bite you later.
DECLARE #CustomerTypes TABLE
(
CustomerTypeID INT,
[Customer Type] VARCHAR(100)
)
INSERT INTO #CustomerTypes
SELECT 1, 'TypeA'
UNION SELECT 2, 'TypeB'
UNION SELECT 3, 'TypeC' --NOTE: An outlier (not in customers-collection)
UNION SELECT 4, 'TypeD' --NOTE: An outlier (not in customers)
DECLARE #Customers TABLE
(
CustomerID INT,
CustomerTypeID INT
)
INSERT INTO #Customers
SELECT 1, 1
UNION SELECT 2, 1
UNION SELECT 3, 1
UNION SELECT 4, 2
UNION SELECT 5, 2
UNION SELECT 6, 2
UNION SELECT 7, 3
DECLARE #CustomersCollection TABLE
(
CollectionID INT IDENTITY(1,1),
CustomerID INT
)
INSERT INTO #CustomersCollection
(CustomerID)
SELECT TOP 2 --INSERT 2 of 3
CustomerID FROM #Customers WHERE CustomerTypeID = 1 --TypeA
INSERT INTO #CustomersCollection
(CustomerID)
SELECT TOP 1 --INSERT 1 of 3
CustomerID FROM #Customers WHERE CustomerTypeID = 2 --TypeB
Second, assemble the CTE data, and generate your output
;WITH CTE_COUNT_TYPE(CustomerTypeID, TypeCount)
AS
(
SELECT CustomerTypeID, COUNT(1)
FROM #Customers
GROUP BY CustomerTypeID
)
--SELECT * FROM CTE_COUNT_TYPE --DEBUG
,
CTE_COUNT_COLLECTION(CustomerTypeID, CollectionCount)
AS
(
SELECT CustomerTypeID, COUNT(1)
FROM #CustomersCollection CC
INNER JOIN #Customers C
ON CC.CustomerID = C.CustomerID
GROUP BY CustomerTypeID
)
--SELECT * FROM CTE_COUNT_COLLECTION --DEBUG
SELECT [Customer Type],
--CONVERT is necessary to combine INT data type (i.e. Count) and VARCHAR data type (i.e. 'as')
CONVERT(VARCHAR(100), COALESCE(CCC.CollectionCount, 0)) +
' of ' +
CONVERT(VARCHAR(100), COALESCE(CCT.TypeCount, 0)) As [Count in Collection]
FROM #CustomerTypes CT
LEFT OUTER JOIN #Customers C --Left outer join assists in outliers
ON CT.CustomerTypeID = C.CustomerTypeID
LEFT OUTER JOIN CTE_COUNT_TYPE CCT --Left outer join assists in outliers
ON CCT.CustomerTypeID = CT.CustomerTypeID
LEFT OUTER JOIN CTE_COUNT_COLLECTION CCC --Left outer join assists in outliers
ON CCC.CustomerTypeID = CT.CustomerTypeID
GROUP BY CT.[Customer Type]
, CCC.CollectionCount
, CCT.TypeCount
Hope so i get the question-
select
ct.CustomerTypeName as [Customer Type],
convert(varchar(30),count(cc.CollectionId)) + ' of ' + convert(varchar(30), count(c.CustomerId)) as [Count in Collection]
from
#Customer c
inner join #CustomerType ct on ct.CustomerTypeId = c.CustomerTypeId
left join #CustomerCollection cc on cc.CustomerId = c.CustomerId
group by
CustomerTypeName
Data script-
declare #customerType table (CustomerTypeId int, CustomerTypeName varchar(100))
insert into #customerType (CustomerTypeId, CustomerTypeName)
select 30, 'TypeA'
union
select 40, 'TypeB'
declare #customer table (CustomerId int, CustomerTypeId int)
insert into #customer (CustomerId, CustomerTypeId)
select 1, 30
union
select 2, 30
union
select 3, 30
union
select 4, 40
union
select 5, 40
union
select 6, 40
declare #customercollection table (CollectionId int, CustomerId int)
insert into #customercollection (CollectionId, CustomerId)
select 100, 1
union
select 200, 2
union
select 300, 5

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

Difference between IN and JOIN

I was wondering what was the difference between the two queries mentioned below, because the first one takes more than 10 seconds to execute on the server and the second one executes in less than one second...
UPDATE - I
Here are the actual queries and their Execution Plans as copied and pasted from SQL Server (as is), sorry for any inconvenience caused by my previous queries... :(
SELECT REPLACE(CONVERT(VARCHAR(11), m.PlanDate, 106), ' ', '-') AS ManagmentPlanDate
FROM ManagmentPlan m
INNER JOIN Product p ON p.Product_ID = m.ProductID
INNER JOIN Category c ON c.C_ID = p.C_ID
LEFT OUTER JOIN Employee e ON e.emp_no = m.PrescribedBy
LEFT OUTER JOIN dbo.Issue_Stock i ON i.serial_no = m.IssueStockID
INNER JOIN dbo.Units u ON u.U_ID = p.U_ID
WHERE ( ( #PatientID IS NULL )
AND ( #VisitID IS NULL )
AND ( m.WardRegNo = #WardRegNo )
)
OR --Get only cuurent admission TP
( ( #PatientID IS NULL )
AND ( #WardRegNo IS NULL )
AND ( VisitID = #VisitID
AND m.WardRegNo IS NULL
)
)
OR -- Get Only Current OPD visit TP
( ( #WardRegNo IS NULL )
AND ( #VisitID IS NULL )
AND ( visitid IN ( SELECT id
FROM PatientVisit
WHERE PatientID = #PatientID ) )
)
OR --Get All Visits TP
( ( #PatientID IS NULL )
AND ( #VisitID IS NOT NULL )
AND ( #WardRegNo IS NOT NULL )
AND ( ( VisitID = #VisitID )
OR ( m.WardRegNo = #WardRegNo )
)
) -- Get Current OPD visit and cuurent admission TP (Both)
AND m.Deleted != 1
AND m.PatientDeptID = #PatientDeptID
GROUP BY REPLACE(CONVERT(VARCHAR(11), m.PlanDate, 106), ' ', '-')
ORDER BY CAST(REPLACE(CONVERT(VARCHAR(11), m.PlanDate, 106), ' ', '-') AS DATETIME) DESC
and
SELECT REPLACE(CONVERT(VARCHAR(11), m.PlanDate, 106), ' ', '-') AS ManagmentPlanDate
FROM ManagmentPlan m
WHERE m.ProductID IN ( SELECT Product_ID
FROM Product
WHERE C_ID IN ( SELECT C_ID
FROM Category )
AND U_ID IN ( SELECT U_ID
FROM Units ) )
AND m.PrescribedBy IN ( SELECT Emp_no
FROM Employee )
AND m.IssueStockID IN ( SELECT Serial_No
FROM Issue_Stock )
AND ( ( #PatientID IS NULL )
AND ( #VisitID IS NULL )
AND ( m.WardRegNo = #WardRegNo )
)
OR --Get only cuurent admission TP
( ( #PatientID IS NULL )
AND ( #WardRegNo IS NULL )
AND ( VisitID = #VisitID
AND m.WardRegNo IS NULL
)
)
OR -- Get Only Current OPD visit TP
( ( #WardRegNo IS NULL )
AND ( #VisitID IS NULL )
AND ( visitid IN ( SELECT id
FROM PatientVisit
WHERE PatientID = #PatientID ) )
)
OR --Get All Visits TP
( ( #PatientID IS NULL )
AND ( #VisitID IS NOT NULL )
AND ( #WardRegNo IS NOT NULL )
AND ( ( VisitID = #VisitID )
OR ( m.WardRegNo = #WardRegNo )
)
) -- Get Current OPD visit and cuurent admission TP (Both)
AND m.Deleted != 1
AND m.PatientDeptID = #PatientDeptID
GROUP BY REPLACE(CONVERT(VARCHAR(11), m.PlanDate, 106), ' ', '-')
ORDER BY CAST(REPLACE(CONVERT(VARCHAR(11), m.PlanDate, 106), ' ', '-') AS DATETIME) DESC
Although, it solved my problem of speed or optimization of the query, but just was curious as to what exactly is the difference between those two queries, as I thought the first one translates to the second one...
UPDATE - I
As you can see, both queries differ in only the JOINS converted to IN statements...
For one, your first statement retrieves all matching records from both the Products and Category tables whereas your second statement only retrieves all matching rows from Products.
What is the performance difference if you change your first statement to
SELECT p.*
FROM Products p
INNER JOIN Category c ON p.CatNo = c.CatNo
Edit
(as mentioned by Martin) note that the number of rows is only identical for both statements if CatNo is unique in the Category table. The INNER JOIN will return as many records as there are in the Category table whereas the IN statement will return as many records as there are unique CatNo in the Category table.
An in clause filters the rows that come back from product. An inner join adds columns from category to the select statement output.