Related
Hello all I have a requirement where I need to filter the rows with multiple conditions and exclude the result if a single entry exists in matching. Here are my sample tables
DECLARE #CUSTOMER TABLE
(
CUSTOMERID INT,
CUSTOMERNAME NVARCHAR(100)
)
DECLARE #ORDER TABLE
(
ORDERID INT,
CUSTOMERID INT,
ISSPECIALORDER INT,
SPECIALORDERID INT
)
DECLARE #SPECIALORDERDTL TABLE
(
SPECIALORDERID INT,
SPECIALORDERDATAID INT
)
DECLARE #SPECIALORDERDATA TABLE
(
SPECIALORDERDATAID INT,
SPECIALORDERMASTERID INT
)
INSERT INTO #CUSTOMER VALUES (100,'CUSTOMER1'),(200,'CUSTOMER2'),(300,'CUSTOMER3'),(400,'CUSTOMER4`enter code here`')
INSERT INTO #ORDER VALUES (1,100,0,1),(2,100,1,1),(3,100,1,2),(4,200,0,1),(5,200,1,1),(6,200,1,4),(7,300,1,5),(8,400,1,6)
INSERT INTO #SPECIALORDERDTL VALUES(1,1),(2,1),(3,2),(4,4)
INSERT INTO #SPECIALORDERDATA VALUES(1,1),(2,1),(3,1),(4,2),(5,2) -- 2 a special order
SELECT C.CUSTOMERID,C.CUSTOMERNAME
FROM #ORDER O
INNER JOIN #CUSTOMER C ON C.CUSTOMERID=O.CUSTOMERID
INNER JOIN #SPECIALORDERDTL SO ON SO.SPECIALORDERID = O.SPECIALORDERID
INNER JOIN #SPECIALORDERDATA SOD ON SO.SPECIALORDERDATAID = SOD.SPECIALORDERDATAID
WHERE SOD.SPECIALORDERID <> 2 AND O.ISSPECIALORDER =0
GROUP BY C.CUSTOMERID,C.CUSTOMERNAME
ORDER BY C.CUSTOMERNAME
When I have an entry in #SPECIALORDERDTL with SPECIALORDERMASTERID as 2 I need to consider them as special entries and exclude those. So my query should return only the customer with 100.
It is not clear from your description or SQL what exactly want. From my understanding:
DECLARE #CUSTOMER TABLE
(
CUSTOMERID INT,
CUSTOMERNAME NVARCHAR(100)
)
DECLARE #ORDER TABLE
(
ORDERID INT,
CUSTOMERID INT,
ISSPECIALORDER INT,
SPECIALORDERID INT
)
DECLARE #SPECIALORDERDTL TABLE
(
SPECIALORDERID INT,
SPECIALORDERDATAID INT
)
DECLARE #SPECIALORDERDATA TABLE
(
SPECIALORDERDATAID INT,
SPECIALORDERMASTERID INT
)
INSERT INTO #CUSTOMER VALUES
(100,'CUSTOMER1'),
(200,'CUSTOMER2'),
(300,'CUSTOMER3'),
(400,'CUSTOMER4')
INSERT INTO #ORDER VALUES
(1,100,0,1),
(2,100,1,1),
(3,100,1,2),
(4,200,0,1),
(5,200,1,1),
(6,200,1,4),
(7,300,1,5),
(8,400,1,6)
INSERT INTO #SPECIALORDERDTL VALUES(1,1),(2,1),(3,2),(4,4)
INSERT INTO #SPECIALORDERDATA VALUES(1,1),(2,1),(3,1),(4,2),(5,2) -- 2 a special order
SELECT C.CUSTOMERID,C.CUSTOMERNAME
from #Customer c
where exists (select * from #ORDER o where o.CustomerId = c.CustomerId)
and not exists (
select *
from #ORDER O
LEFT JOIN #SPECIALORDERDTL SO ON SO.SPECIALORDERID = O.SPECIALORDERID
LEFT JOIN #SPECIALORDERDATA SOD ON SO.SPECIALORDERDATAID = SOD.SPECIALORDERDATAID
WHERE (SO.SPECIALORDERID IS NULL
or SOD.SPECIALORDERMASTERID = 2 --AND O.ISSPECIALORDER =0
) AND O.CustomerId = c.CustomerId
);
GO
CUSTOMERID | CUSTOMERNAME
---------: | :-----------
100 | CUSTOMER1
db<>fiddle here
Assuming I understand the question, I think a conditional aggregation in the having clause is probably the simplest way to get the result you want:
SELECT C.CUSTOMERID, C.CUSTOMERNAME
FROM #CUSTOMER As C
JOIN #ORDER O
ON C.CUSTOMERID = O.CUSTOMERID
JOIN #SPECIALORDERDTL SO
ON O.SPECIALORDERID = SO.SPECIALORDERID
JOIN #SPECIALORDERDATA SOD
ON SO.SPECIALORDERDATAID = SOD.SPECIALORDERDATAID
GROUP BY C.CUSTOMERID, C.CUSTOMERNAME
HAVING COUNT(CASE WHEN SOD.SPECIALORDERMASTERID = 2 THEN 1 END) = 0
The having clause will filter out every customer where at least one of the orders associated with them have a specialordermasterid of 2.
From your description it sounds like not every customer will have an entry in SPECIALORDERDTL or SPECIALORDERDTA so you don't want to inner join to those tables.
What you need is a "not exists" correlated subquery to check that the customers do not have a matching row in those tables.
So you can remove the inner joins to SPECIAL* tables and add something like:-
where not exists (select null from SPECIALORDERDTL SO where
SO.SPECIALORDERID = O.SPECIALORDERID and SO.SPECIALORDERMASTERID = 2)
From your description I'm not quite sure where "SOD.SPECIALORDERID <> 2 AND O.ISSPECIALORDER =0" fit into it, so please give further details of outputs if you can't resolve using subquery.
Following your clarification, please try something like this:-
SELECT distinct C.CUSTOMERID,C.CUSTOMERNAME
FROM #ORDER O
INNER JOIN #CUSTOMER C ON C.CUSTOMERID=O.CUSTOMERID
where not exists
(select null from #SPECIALORDERDTL SO
INNER JOIN #SPECIALORDERDATA SOD ON SO.SPECIALORDERDATAID = SOD.SPECIALORDERDATAID
where SO.SPECIALORDERID = O.SPECIALORDERID and
SOD.SPECIALORDERMASTERID = 2
)
order by C.CUSTOMERNAME
I have the following SQL query statement:
INSERT INTO #mt_API
SELECT
[dbo].fn_AddTimeZoneOffset(APHIST.ActionDate,'CET') AS ASDATE
, [dbo].fn_AddTimeZoneOffset(APHIST.ReturnDate,'CET') AS ATDATE
,API_HIST.[ActionPlanItemID]
,API_HIST.[ActionPlanID]
,PIT.[ProductItemID]
,PIT.ProductItemCode
,PIT.QRCode
,PIT.Name
,ISNULL((SELECT TOP 1 mRSP.TotalRemainingAtStore FROM #mt_RemainingStockProduct AS mRSP
WHERE mRSP.InventoryDate <= APHIST.ReturnDate
ORDER BY mRSP.InventoryDate DESC), 0) AS StoreTotalStock
,P.[Weight] AS ItemWeight
,M.UnitMeasureCode as Unit
,PIT.Quantity AS ItemQuantity
,P.ItemUnitWeight
,P.Quantity as ProductQuantity
,E1.FullName AS Emp1
,E2.FullName AS Emp2
,E3.FullName AS Emp3
,E4.FullName AS Emp4
,SECT.Name AS Sector
,CASE WHEN n=0 then 0 else [ItemStatus] end as [ItemStatus]
,APHIST.IsActionOver as ActionOver
FROM
[Sales].[ActionPlanItem_History] AS API_HIST
INNER JOIN
[Sales].[ActionPlan_History] AS APHIST On APHIST.ActionPlanID = API_HIST.ActionPlanID
INNER JOIN
[Production].[ProductItem] AS PIT ON API_HIST.ProductItemID =PIT.ProductItemID
INNER JOIN
Production.Product as P ON PIT.ProductID = P.ProductID AND PIT.ProductID = P.ProductID AND
PIT.ProductID = P.ProductID
INNER JOIN
Production.UnitMeasure as M ON M.UnitMeasureID = P.WeightUnitMeasureID
LEFT OUTER JOIN
Sales.Employee AS E1 ON APHIST.EmployeeID1 = E1.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E2 ON APHIST.EmployeeID2 = E2.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E3 ON APHIST.EmployeeID3 = E3.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E4 ON APHIST.EmployeeID4 = E4.EmployeeID
INNER JOIN
Sales.Sector AS SECT ON APHIST.SectorID = SECT.SectorID
INNER JOIN
Production.ProductSubcategory as PS on P.ProductSubcategoryID=PS.ProductSubcategoryID
INNER JOIN
Production.ProductCategory as PC on PS.ProductCategoryID= PC.ProductCategoryID
CROSS APPLY (Values(0),(1)) d(n)
WHERE P.StoreID=#StoreID
--WHERE PC.ProductCategoryID=#RootCategory AND P.StoreID=#StoreID
--ORDER BY ProductItemCode, ATDATE
ORDER BY ASDATE , ProductItemCode
SELECT
API1.ASDATE AS StartDate
,API1.ATDATE AS ReturnDate
,API1.ActionPlanItemID
,API1.ActionPlanID
,API1.ProductItemID
,API1.ProductItemCode
,API1.QRCode
,API1.Name
,API1.StoreTotalStock
,API1.ItemWeight
,API1.ItemQuantity
,API1.ItemUnitWeight
,API1.Unit
,API1.ProductQuantity
,API1.Emp1
,API1.Emp2
,API1.Emp3
,API1.Emp4
,API1.Sector
,API1.ItemStatus
,API1.ActionOver
,(API1.StoreTotalStock +
(SELECT SUM(
CASE API2.ItemStatus
WHEN 0 THEN -1
WHEN 1 THEN 1
ELSE 0
END * API2.ItemUnitWeight)
FROM #mt_API AS API2
WHERE API2.ID <= API1.ID
)
-
(
**select
case ISNULL(SUM([ProductItemWeight]), 0)
when 0 then 0
else SUM([ProductItemWeight])
end
from [ExplosiveTracking].[Production].[TransfertHistory]
where stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') < stuff(convert(varchar(20),API1.ASDATE,120),17,6,'')**
)
) AS ItemWeightBal
FROM #mt_API AS API1
Inside the CASE statement I am returning the SUM([ProductItemWeight]) if it is not NULL, but then at same time, I need to execute the following inside the same CASE :
delete from #tempTransfert
where stuff(convert(varchar(20),#tempTransfert.TransferDate,120),17,6,'') < stuff(convert(varchar(20),API1.ASDATE,120),17,6,'')
ADDED MORE TEST :
If I run what I wan to accomplish in a standalone new query as below then the DELETE and SELECT works find inside the CASE
CREATE TABLE #tempTransfert
(
[ID] uniqueidentifier,
[ProductId] int,
[SourceId] int,
TransferDate DateTime,
TotalMovedProduct DECIMAL(16,4)
)
Insert into #tempTransfert
select
[ID],[ProductId], [SourceId], stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') as TransferDate, SUM([ProductItemWeight]) as TotalMovedProduct
from [ExplosiveTracking].[Production].[TransfertHistory]
group by [ProductId],ID, [SourceId], stuff(convert(varchar(20),TransfertDateTime,120),17,6,'')
select * from #tempTransfert
MERGE #tempTransfert AS T
USING (select
case ISNULL(SUM([ProductItemWeight]) , 0)
when 0 then 0
else SUM([ProductItemWeight])
end
, ID
from [ExplosiveTracking].[Production].[TransfertHistory]
where stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') < stuff(convert(varchar(20),'2017-02-28 15:38:00',120),17,6,'')
Group by ID
) as S ([ProductItemWeight],ID)
ON (T.ID = S.ID)
WHEN MATCHED
THEN DELETE;
BUT when I added in the complete query as below , I have a SYNTAX error near MERGE reported :
DECLARE #m_StoreTotalStock AS DECIMAL(18,3)
DECLARE #mt_API AS TABLE
(
ID INT IDENTITY(1,1), ASDATE DATETIME,ATDATE DATETIME,
ActionPlanItemID INT, ActionPlanID INT,
ProductItemID INT, ProductItemCode VARCHAR(50),
QRCode VARCHAR(50), Name VARCHAR(50),
StoreTotalStock decimal(18,3), ItemWeight decimal(18,3),
Unit VARCHAR(50), ItemQuantity INT,
ItemUnitWeight DECIMAL(18,4), ProductQuantity INT,
Emp1 VARCHAR(50), Emp2 VARCHAR(50),
Emp3 VARCHAR(50), Emp4 VARCHAR(50),
Sector VARCHAR(50), ItemStatus TINYINT,ActionOver INt
)
DECLARE #mt_RemainingStockProduct AS TABLE
(
StoreID INT,InventoryDate DATETIME,ProductID INT, TotalRemainingAtStore DECIMAL(18,2)
)
CREATE TABLE #tempTransfert
(
[ID] uniqueidentifier,
[ProductId] int,
[SourceId] int,
TransferDate DateTime,
TotalMovedProduct DECIMAL(16,4)
)
Insert into #tempTransfert
select
[ID],[ProductId], [SourceId], stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') as TransferDate, SUM([ProductItemWeight]) as TotalMovedProduct
from [ExplosiveTracking].[Production].[TransfertHistory]
group by [ProductId],ID, [SourceId], stuff(convert(varchar(20),TransfertDateTime,120),17,6,'')
select * from #tempTransfert
/** Get Remaining StockBy Product **/
INSERT INTO #mt_RemainingStockProduct
(
StoreID, InventoryDate, ProductID,TotalRemainingAtStore
)
--SELECT InventoryDate, SUM(TotalRemainingAtStore) AS TotalRemainingAtStore FROM
--(
SELECT StoreID, InventoryDate, ProductID, SUM(Remaining) OVER (PARTITION BY StoreID ) AS TotalRemainingAtStore FROM
(
SELECT
P.StoreID, P.InventoryDate, P.ProductID,
--SUM(PIT.Quantity * P.ItemUnitWeight)-SUM(PIT.UsedQuantity * P.ItemUnitWeight) AS Remaining
SUM(PIT.Quantity * P.ItemUnitWeight) AS Remaining
FROM Sales.Store AS S
INNER JOIN Production.ProductItem AS PIT
INNER JOIN Production.Product AS P ON PIT.ProductID = P.ProductID
INNER JOIN Production.UnitMeasure AS UM ON P.WeightUnitMeasureID = UM.UnitMeasureID ON
S.BusinessEntityID = P.StoreID
INNER JOIN Production.Location AS LOC ON S.BusinessEntityID = LOC.StoreID AND
P.LocationID = LOC.LocationID AND P.LocationID = LOC.LocationID
WHERE (P.IsDeleted = 0) AND (PIT.IsDeleted = 0) AND P.StoreID = 4
GROUP BY P.StoreID,P.InventoryDate, P.ProductID, UM.UnitMeasureCode, S.Name, LOC.MaxQuantity
) AS RST1
--) AS RST2
--GROUP BY RST2.InventoryDate
/** Endof Get Remaining StockBy Product **/
-- Get Store total product items weight
SELECT #m_StoreTotalStock = SUM(PIW.TotalWeight)
FROM dbo.v_ProductItemWeight AS PIW
WHERE StoreID = 4
INSERT INTO #mt_API
SELECT [dbo].fn_AddTimeZoneOffset(APHIST.ActionDate,'CET') AS ASDATE
, [dbo].fn_AddTimeZoneOffset(APHIST.ReturnDate,'CET') AS ATDATE
,API_HIST.[ActionPlanItemID]
,API_HIST.[ActionPlanID]
,PIT.[ProductItemID]
,PIT.ProductItemCode
,PIT.QRCode
,PIT.Name
,ISNULL((SELECT TOP 1 mRSP.TotalRemainingAtStore FROM #mt_RemainingStockProduct AS mRSP
WHERE mRSP.InventoryDate <= APHIST.ReturnDate
ORDER BY mRSP.InventoryDate DESC), 0) AS StoreTotalStock
,P.[Weight] AS ItemWeight
,M.UnitMeasureCode as Unit
,PIT.Quantity AS ItemQuantity
,P.ItemUnitWeight
,P.Quantity as ProductQuantity
,E1.FullName AS Emp1
,E2.FullName AS Emp2
,E3.FullName AS Emp3
,E4.FullName AS Emp4
,SECT.Name AS Sector
,CASE WHEN n=0 then 0 else [ItemStatus] end as [ItemStatus]
,APHIST.IsActionOver as ActionOver
FROM
[Sales].[ActionPlanItem_History] AS API_HIST
INNER JOIN
[Sales].[ActionPlan_History] AS APHIST On APHIST.ActionPlanID = API_HIST.ActionPlanID
INNER JOIN
[Production].[ProductItem] AS PIT ON API_HIST.ProductItemID =PIT.ProductItemID
INNER JOIN
Production.Product as P ON PIT.ProductID = P.ProductID AND PIT.ProductID = P.ProductID AND
PIT.ProductID = P.ProductID
INNER JOIN
Production.UnitMeasure as M ON M.UnitMeasureID = P.WeightUnitMeasureID
LEFT OUTER JOIN
Sales.Employee AS E1 ON APHIST.EmployeeID1 = E1.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E2 ON APHIST.EmployeeID2 = E2.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E3 ON APHIST.EmployeeID3 = E3.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E4 ON APHIST.EmployeeID4 = E4.EmployeeID
INNER JOIN
Sales.Sector AS SECT ON APHIST.SectorID = SECT.SectorID
INNER JOIN
Production.ProductSubcategory as PS on P.ProductSubcategoryID=PS.ProductSubcategoryID
INNER JOIN
Production.ProductCategory as PC on PS.ProductCategoryID= PC.ProductCategoryID
CROSS APPLY (Values(0),(1)) d(n)
WHERE P.StoreID=4
--WHERE PC.ProductCategoryID=#RootCategory AND P.StoreID=#StoreID
--ORDER BY ProductItemCode, ATDATE
ORDER BY ASDATE , ProductItemCode
SELECT
API1.ASDATE AS StartDate
,API1.ATDATE AS ReturnDate
,API1.ActionPlanItemID
,API1.ActionPlanID
,API1.ProductItemID
,API1.ProductItemCode
,API1.QRCode
,API1.Name
,API1.StoreTotalStock
,API1.ItemWeight
,API1.ItemQuantity
,API1.ItemUnitWeight
,API1.Unit
,API1.ProductQuantity
,API1.Emp1
,API1.Emp2
,API1.Emp3
,API1.Emp4
,API1.Sector
,API1.ItemStatus
,API1.ActionOver
,(API1.StoreTotalStock +
(SELECT SUM(
CASE API2.ItemStatus
WHEN 0 THEN -1
WHEN 1 THEN 1
ELSE 0
END * API2.ItemUnitWeight)
FROM #mt_API AS API2
WHERE API2.ID <= API1.ID
)
-
--select
-- case ISNULL(SUM([ProductItemWeight]), 0)
-- when 0 then 0
-- else SUM([ProductItemWeight])
-- end
--from [ExplosiveTracking].[Production].[TransfertHistory]
--where stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') < stuff(convert(varchar(20),API1.ASDATE,120),17,6,'')
(
**MERGE #tempTransfert AS T
USING (select
case ISNULL(SUM([ProductItemWeight]) , 0)
when 0 then 0
else SUM([ProductItemWeight])
end
, ID
from [ExplosiveTracking].[Production].[TransfertHistory]
where stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') < stuff(convert(varchar(20),API1.ASDATE,120),17,6,'')
Group by ID
) as S ([ProductItemWeight],ID)
ON (T.ID = S.ID)
WHEN MATCHED
THEN DELETE;
)**
) AS ItemWeightBal
FROM #mt_API AS API1
END
The MERGE part is suppose to first return the SUM of ItemWeight within a DateTime range, then when those records has been read, I need to delete them from #tempTransfert table otherwise, on the next loop it will read all records again
Any idea what syntax error can it be ?
Thanks for your help on this
Regards
So my stored procedure has a staff column that should be generating a staff name from my Employee table. The staff name only shows up on for some of the rows. Can anyone take a look and see where my error is here:
BEGIN
IF EXISTS (SELECT 1 FROM [user] (NOLOCK)
WHERE [user].ID = #UserID
AND [user].BrandID IS NULL AND [user].SpaID IS NULL)
BEGIN
DECLARE #OrderStatusID_Completed int, #OrderStatusID_Shipped int
SET #OrderStatusID_Shipped = 4
SET #OrderStatusID_Completed = 2
SELECT
CAST('' AS varchar(50)) AS ErrMsg
, o.OrderNumber
, Customer.GUID AS CustomerGUID
, OrderItem_View.DateCreated AS ItemDate
, COALESCE(MasterProductVariant.SKU, ProductVariant.SKU, Treatment.SKU) AS SKU
, DynamicPrice.FinalPrice AS Price
--, COALESCE(MasterProductVariant.OriginalPrice, ProductVariant.OriginalPrice, Treatment.Price) AS Price
, ISNULL(Employee.FirstName,'') + ' ' + ISNULL(Employee.LastName,'') AS Staff
, COALESCE(Product.Name, Treatment.Name) AS Item
, NULL AS Note
FROM
[Order] o (Nolock)
LEFT JOIN
Customer (Nolock) ON o.CustomerID = Customer.ID
INNER JOIN
OrderItem_View (nolock) ON OrderItem_View.OrderID = o.ID
LEFT JOIN
DynamicPrice (nolock) ON OrderItem_View.DynamicPriceID = DynamicPrice.ID
LEFT JOIN
AppointmentTreatment WITH (NOLOCK) ON AppointmentTreatment.ID = OrderItem_View.AppointmentTreatmentID
LEFT JOIN
Employee (NOLOCK) ON Employee.ID = COALESCE(OrderItem_View.EmployeeID, OrderItem_View.Employee2ID, AppointmentTreatment.EmployeeID)
LEFT JOIN
Treatment_View Treatment (nolock) ON Treatment.BillableItemID = OrderItem_View.BillableItemID
LEFT JOIN
ProductVariant (NOLOCK)
LEFT JOIN
Product (NOLOCK) ON Product.ID = ProductVariant.ProductID
ON ProductVariant.BillableItemID = OrderItem_View.BillableItemID
LEFT JOIN
ProductVariant MasterProductVariant (NOLOCK) ON ProductVariant.MasterRecordID = MasterProductVariant.ID
WHERE
o.SpaID = #SpaID
AND o.IsDeleted = 0
AND o.DateCompleted >= CONVERT(DATETIME,0)
AND o.DateCompleted < GetDate()
AND o.StatusID IN (#OrderStatusID_Completed,#OrderStatusID_Shipped)
END
ELSE
SELECT CAST('Insufficient rights.' AS VARCHAR(50)) AS ErrMsg
END
It has to be in the coalesce function. Somewhere between these three - you aren't getting a value
OrderItem_View.EmployeeID
OrderItem_View.Employee2ID
AppointmentTreatment.EmployeeID
So run OrderItem_View by itself and see if there are instances where EmployeeID or Employee2ID is ever null. If so, then try to determine what employees are missing. IF there are employees missing, are they also missing in the AppointmentTreatment table? If so then therein lies the problem.
I have a stored procedure on my SQL Server that consolidates a range of fields for use in SSRS for Report Builder. The procedure is fed a FileId and then works its logic. It works as intended until the File can't find or reference the Solicitor and Arresting Officer fields.
I need this to return a result even if the fileId does not have an Arresting Officer or Solicitor associated. I'm sure its something simple. Basically if the CTE returns nothing from the query, I still need a default row.
ALTER PROCEDURE [dbo].[GetRollCallData]
#Ids VARCHAR(255),
#LexiconId INT,
#UUID UNIQUEIDENTIFIER,
#ReadOnly INT
AS
DECLARE #TableCode INT
SET #TableCode = 58
IF #Ids <> ''
BEGIN
EXEC InsertInSelectionCache #Ids, #UUID, #TableCode, 0
IF #ReadOnly = 1
WITH DOACTE AS(
SELECT ROW_NUMBER() OVER(PARTITION BY [File].Id ORDER BY CustomRecordsetId DESC) AS RowNumber, [File].*, FileType2Lexicon.Label as FileTypeLabel, [People].DefaultPhone, [People].InvertedName, CustomField.Name as FieldLabel, CustomFieldValue.Value as FieldValue
FROM FileType2Lexicon, SelectionCache, [People], [File]
INNER JOIN [CustomRecordSet]
ON [CustomRecordset].RecordId = [File].Id
INNER JOIN CustomFieldValue
ON [CustomRecordset].Id = CustomFieldValue.CustomRecordsetId
INNER JOIN [CustomField2Lexicon]
ON CustomField2Lexicon.CustomFieldId = CustomFieldValue.CustomFieldId
INNER JOIN [CustomField]
ON CustomField.Id = CustomField2Lexicon.CustomFieldId
WHERE [File].Id = SelectionCache.RecordId
AND SelectionCache.UUID = #UUID
AND SelectionCache.TableCode = #TableCode -- this is the code for File table
AND [File].Id <> 0
AND [File].FileTypeId = FileType2Lexicon.FileTypeId
AND FileType2Lexicon.LexiconId = #LexiconId
AND [File].ClientIdString = [People].ClientIdString
AND CustomFieldValue.Value <> ''),
SolicitorCTE AS(
SELECT [People].Name AS SolicitorName, [File].Id
FROM SelectionCache, [File]
INNER JOIN [People2File]
ON [People2File].FileId = [File].Id
INNER JOIN [Role2Lexicon]
ON [Role2Lexicon].RoleId = [People2File].RoleId
INNER JOIN [People]
ON [People].Id = [People2File].PeopleId
WHERE
[File].Id = SelectionCache.RecordId
AND SelectionCache.UUID = #UUID
AND SelectionCache.TableCode = #TableCode -- this is the code for File table
AND [File].Id <> 0
AND [Role2Lexicon].Label = 'Solicitor'),
ArrestingOfficerCTE AS(
SELECT ROW_NUMBER() OVER(PARTITION BY [File].Id ORDER BY [People].InvertedName ASC) AS RowNumber, [People].Name AS ArrestingOfficerName, [People].CompanyName AS ArrestingOfficerCompany, [File].Id
FROM SelectionCache, [File]
INNER JOIN [People2File]
ON [People2File].FileId = [File].Id
INNER JOIN [Role2Lexicon]
ON [Role2Lexicon].RoleId = [People2File].RoleId
INNER JOIN [People]
ON [People].Id = [People2File].PeopleId
WHERE
[File].Id = SelectionCache.RecordId
AND SelectionCache.UUID = #UUID
AND SelectionCache.TableCode = #TableCode -- this is the code for File table
AND [File].Id <> 0
AND [Role2Lexicon].Label = 'Arresting Officer'),
PivotCTE AS(
SELECT *
FROM
(Select Id, FieldLabel, FieldValue FROM DOACTE) AS Source
PIVOT(
MAX(FieldValue) FOR FieldLabel IN ([Date_Arrest], [Graphic_Client], [Ticket_1], [Ticket_2], [Ticket_3], [Ticket_4], [Ticket_5], [Charge_1], [Charge_2], [Charge_3], [Charge_4], [Charge_5])) as Pvt
)
SELECT DOACTE.*, COALESCE(ArrestingOfficerCTE.ArrestingOfficerCompany, 'NULL')AS ArrestingOfficerCompany, COALESCE(ArrestingOfficerCTE.ArrestingOfficerName, 'NULL') AS ArrestingOfficerName, SolicitorCTE.SolicitorName, PivotCTE.[Date_Arrest], dbo.GetImagebyId(PivotCTE.[Graphic_Client]) as Photo, PivotCTE.[Ticket_1], PivotCTE.[Ticket_2], PivotCTE.[Ticket_3], PivotCTE.[Ticket_4], PivotCTE.[Ticket_5], PivotCTE.[Charge_1], PivotCTE.[Charge_2], PivotCTE.[Charge_3], PivotCTE.[Charge_4], PivotCTE.[Charge_5]
FROM DOACTE
INNER JOIN
PivotCTE
ON DOACTE.Id = PivotCTE.Id
INNER JOIN
SolicitorCTE
ON DOACTE.Id = SolicitorCTE.Id
INNER JOIN
ArrestingOfficerCTE
ON DOACTE.Id = ArrestingOfficerCTE.Id
WHERE DOACTE.RowNumber = 1
AND ArrestingOfficerCTE.RowNumber = 1
ELSE
DELETE SelectionCache
WHERE UUID = #UUID
AND TableCode = #TableCode
END
You can left join for optional results. I also needed to add a null check for the Arresting officer to the where caluse so that this didn't exclude records despite the left join.
SELECT DOACTE.*, COALESCE(ArrestingOfficerCTE.ArrestingOfficerCompany, 'NULL')AS ArrestingOfficerCompany, COALESCE(ArrestingOfficerCTE.ArrestingOfficerName, 'NULL') AS ArrestingOfficerName, SolicitorCTE.SolicitorName, PivotCTE.[Date_Arrest], dbo.GetImagebyId(PivotCTE.[Graphic_Client]) as Photo, PivotCTE.[Ticket_1], PivotCTE.[Ticket_2], PivotCTE.[Ticket_3], PivotCTE.[Ticket_4], PivotCTE.[Ticket_5], PivotCTE.[Charge_1], PivotCTE.[Charge_2], PivotCTE.[Charge_3], PivotCTE.[Charge_4], PivotCTE.[Charge_5]
FROM DOACTE
INNER JOIN
PivotCTE
ON DOACTE.Id = PivotCTE.Id
LEFT JOIN
SolicitorCTE
ON DOACTE.Id = SolicitorCTE.Id
LEFT JOIN
ArrestingOfficerCTE
ON DOACTE.Id = ArrestingOfficerCTE.Id
WHERE DOACTE.RowNumber = 1
AND ( ArrestingOfficerCTE.RowNumber = 1 or ArrestingOfficerCTE.RowNumber is null )
Can you try:
SELECT DOACTE.*, COALESCE(ArrestingOfficerCTE.ArrestingOfficerCompany, 'NULL')AS ArrestingOfficerCompany, COALESCE(ArrestingOfficerCTE.ArrestingOfficerName, 'NULL') AS ArrestingOfficerName, SolicitorCTE.SolicitorName, PivotCTE.[Date_Arrest], dbo.GetImagebyId(PivotCTE.[Graphic_Client]) as Photo, PivotCTE.[Ticket_1], PivotCTE.[Ticket_2], PivotCTE.[Ticket_3], PivotCTE.[Ticket_4], PivotCTE.[Ticket_5], PivotCTE.[Charge_1], PivotCTE.[Charge_2], PivotCTE.[Charge_3], PivotCTE.[Charge_4], PivotCTE.[Charge_5]
into #Results
FROM DOACTE
INNER JOIN
PivotCTE
ON DOACTE.Id = PivotCTE.Id
INNER JOIN
SolicitorCTE
ON DOACTE.Id = SolicitorCTE.Id
INNER JOIN
ArrestingOfficerCTE
ON DOACTE.Id = ArrestingOfficerCTE.Id
WHERE DOACTE.RowNumber = 1
AND ArrestingOfficerCTE.RowNumber = 1
if ((select cout(*) from #Results) = 0)
begin
insert into #Results
select
.......your default values......
end
select * from #Results
drop table #Results
This is pretty much liebs19's answer, so I upvoted his since he got there first. I think the answer comes down to LEFT JOINing where you're INNER. Since I rewrote your query so I could actually understand what was going on and I made some changes you may or may not want, so I'll leave it here in case it's useful.
Mine is more lines than yours partially because I format differently, partially because I'm using a temp table to do once what you do around 4 times. Thing about CTE's is that when you stack them like this you're likely to get some really gnarly performance. The CTE's act basically like an on-the-fly view, and their SQL pretty much gets repeated everywhere. I'm taking your limiting [File] and moving it into a temp table. Then I'm pivoting it into another one (since this further limits things based on RowNumber being 1. Then I just use this with the 2 CTE's at the end and into your final result.
Lastly, SELECT * ... is evil. I only use it when I'm poking around querying for something. Putting it into a sproc like this will cause you issues as the schema or CTE's or so on change. When you're making a sproc, name every column, it'll bite you much less in the future.
Here it is, feel free to ignore if you don't find it useful:
ALTER PROCEDURE [dbo].[GetRollCallData]
#Ids VARCHAR(255),
#LexiconId INT,
#UUID UNIQUEIDENTIFIER,
#ReadOnly INT
AS
BEGIN
DECLARE #TableCode INT = 58;
IF #Ids <> ''
BEGIN
EXEC InsertInSelectionCache #Ids, #UUID, #TableCode, 0
IF #ReadOnly = 1
BEGIN
SELECT
-- Add any other fully qualified columns. * is evil for sprocs. Only good for poking around in your own queries.
AllFiles.Id
INTO #SelectionFile
FROM
[File] AllFiles
INNER JOIN SelectionCache Cache
ON Cache.RecordId = AllFiles.Id
AND Cache.UUID = #UUID
AND Cache.TableCode = #TableCode -- this is the code for File table
WHERE
AllFiles.Id <> 0
;WITH DOACTE AS
(
SELECT
ROW_NUMBER() OVER(PARTITION BY SelectionFile.Id ORDER BY CustomRecordsetId DESC) AS RowNumber
, SelectionFile.Id AS FileId
-- [Replace with any other columns that you selected from [File] at the top.]
, Lexicon.Label AS FileTypeLabel
, [People].DefaultPhone
, [People].InvertedName
, CustomField.Name AS FieldLabel
, CustomFieldValue.Value AS FieldValue
FROM
#SelectionFile SelectionFile
INNER JOIN FileType2Lexicon Lexicon
ON Lexicon.FileTypeId = SelectionFile.FileTypeId
AND Lexicon.LexiconId = #LexiconId
INNER JOIN [People]
ON [People].ClientIdString = SelectionFile.ClientIdString
INNER JOIN [CustomRecordSet]
ON [CustomRecordset].RecordId = SelectionFile.Id
INNER JOIN CustomFieldValue
ON [CustomRecordset].Id = CustomFieldValue.CustomRecordsetId
AND CustomFieldValue.Value <> ''
INNER JOIN [CustomField2Lexicon]
ON CustomField2Lexicon.CustomFieldId = CustomFieldValue.CustomFieldId
INNER JOIN [CustomField]
ON CustomField.Id = CustomField2Lexicon.CustomFieldId
)
SELECT
Pvt.FileId
-- [Replace with any other columns that you selected from DOACTE you want to propagate to the end.]
, Pvt.[Date_Arrest]
, Pvt.[Graphic_Client]
, Pvt.[Ticket_1]
, Pvt.[Ticket_2]
, Pvt.[Ticket_3]
, Pvt.[Ticket_4]
, Pvt.[Ticket_5]
, Pvt.[Charge_1]
, Pvt.[Charge_2]
, Pvt.[Charge_3]
, Pvt.[Charge_4]
, Pvt.[Charge_5]
INTO #PivotedFile
FROM
(
SELECT
FileId
-- [Replace with any other columns that you selected from DOACTE you want to propagate to the end.]
, FieldLabel
, FieldValue
, FieldLabel AS PivotFieldLabel
, FieldValue AS PivotFieldValue
FROM
DOACTE
WHERE
RowNumber = 1
) AS Source
PIVOT
(
MAX(PivotFieldValue)
FOR PivotFieldLabel
IN
(
[Date_Arrest]
, [Graphic_Client]
, [Ticket_1]
, [Ticket_2]
, [Ticket_3]
, [Ticket_4]
, [Ticket_5]
, [Charge_1]
, [Charge_2]
, [Charge_3]
, [Charge_4]
, [Charge_5]
)
) as Pvt
;WITH SolicitorCTE AS
(
SELECT
[People].Name AS SolicitorName
, SelectedFiles.FileId
FROM
#PivotedFile SelectedFiles
INNER JOIN [People2File]
ON [People2File].FileId = SelectedFiles.FileId
INNER JOIN [Role2Lexicon]
ON [Role2Lexicon].RoleId = [People2File].RoleId
AND [Role2Lexicon].Label = 'Solicitor'
INNER JOIN [People]
ON [People].Id = [People2File].PeopleId
)
, ArrestingOfficerCTE AS
(
SELECT
ROW_NUMBER() OVER(PARTITION BY SelectionFile.Id ORDER BY [People].InvertedName ASC) AS RowNumber
, [People].Name AS ArrestingOfficerName
, [People].CompanyName AS ArrestingOfficerCompany
, SelectedFiles.FileId
FROM
#PivotedFile SelectedFiles
INNER JOIN [People2File]
ON [People2File].FileId = SelectedFiles.FileId
INNER JOIN [Role2Lexicon]
ON [Role2Lexicon].RoleId = [People2File].RoleId
AND [Role2Lexicon].Label = 'Arresting Officer'
INNER JOIN [People]
ON [People].Id = [People2File].PeopleId
)
SELECT
SelectedFiles.Id
-- [Replace with any other columns that you selected from DOACTE you want to propagate to the end.]
, COALESCE(ArrestingOfficerCTE.ArrestingOfficerCompany, 'NULL') AS ArrestingOfficerCompany
, COALESCE(ArrestingOfficerCTE.ArrestingOfficerName, 'NULL') AS ArrestingOfficerName
, SolicitorCTE.SolicitorName
, SelectedFiles.[Date_Arrest]
, dbo.GetImagebyId(SelectedFiles.[Graphic_Client]) as Photo
, SelectedFiles.[Ticket_1]
, SelectedFiles.[Ticket_2]
, SelectedFiles.[Ticket_3]
, SelectedFiles.[Ticket_4]
, SelectedFiles.[Ticket_5]
, SelectedFiles.[Charge_1]
, SelectedFiles.[Charge_2]
, SelectedFiles.[Charge_3]
, SelectedFiles.[Charge_4]
, SelectedFiles.[Charge_5]
FROM #PivotedFile SelectedFiles
LEFT JOIN SolicitorCTE
ON SelectedFiles.FileId = SolicitorCTE.FileId
LEFT JOIN ArrestingOfficerCTE
ON SelectedFiles.FileId = ArrestingOfficerCTE.FileId
AND ArrestingOfficerCTE.RowNumber = 1
DROP TABLE #SelectionFile
DROP TABLE #PivotedFile
END
ELSE
DELETE SelectionCache
WHERE
UUID = #UUID
AND TableCode = #TableCode
END
END
(If you do use it, read the -- [Replace...] comments.
I want to get data historical and the production. My stored procedure is as follows:
ALTER PROCEDURE [dbo].[pCaRptACInactivas](
#CodAsesor VARCHAR(15),
#CodOficina VARCHAR(4))
AS
SET NOCOUNT ON
DECLARE #CodArbolConta VARCHAR(25)
IF #CodOficina = '%'
SET #CodArbolConta = '%'
ELSE
SELECT #CodArbolConta = CodArbolConta + '%' FROM tClOficinas WHERE CodOficina LIKE #CodOficina
SELECT
tabACInactivas.CodOficina,
tabACInactivas.NomOficina,
tabACInactivas.NomAsesor,
MAX(tabACInactivas.CodPrestamo) CodPrestamo,
tabACInactivas.CodAsociacion,
tabACInactivas.NombreAsociacion,
MAX(tabACInactivas.Ciclo) AS Ciclo,
COUNT(DISTINCT tabACInactivas.CodUsuario) AS CantSocias,
MAX(tabACInactivas.FechaEstado) AS FechaCancelacion--,
FROM ( SELECT tClOficinas.CodOficina, tClOficinas.NomOficina, tCaClAsesores.CodAsesor, tCaClAsesores.NomAsesor, tCaPrestamos.CodPrestamo, tCaAsociacion.CodAsociacion, tCaAsociacion.NombreAsociacion, tCaPrestamos.Ciclo, tCaPrCliente.CodUsuario, tCaPrestamos.FechaEstado, tClParametros.FechaProceso FROM tCaPrestamos WITH(NOLOCK) INNER JOIN tCaProducto WITH(NOLOCK) ON tCaProducto.CodProducto = tCaPrestamos.CodProducto INNER JOIN tClOficinas WITH(NOLOCK) ON tClOficinas.CodOficina = tCaPrestamos.CodOficina INNER JOIN tCaAsociacion WITH(NOLOCK) ON tCaAsociacion.CodAsociacion = tCaPrestamos.CodAsociacion INNER JOIN tCaPrCliente WITH(NOLOCK) ON tCaPrCliente.CodPrestamo = tCaPrestamos.CodPrestamo INNER JOIN tClParametros WITH(NOLOCK) ON tClParametros.CodOficina = tClOficinas.CodOficina INNER JOIN tCaClAsesores ON tCaClAsesores.CodAsesor = tCaAsociacion.CodAsesor WHERE tCaPrestamos.Estado = 'CANCELADO' AND DATEDIFF(DAY, tCaPrestamos.FechaEstado, tClParametros.FechaProceso) > 30 AND NOT EXISTS(SELECT 1
FROM tCaPrestamos Pr
INNER JOIN tCaPrCliente PrCl ON PrCl.CodPrestamo = Pr.CodPrestamo
WHERE Pr.Estado NOT IN ('TRAMITE', 'APROBADO')
AND Pr.FechaDesembolso >= tCaPrestamos.FechaEstado
AND Pr.CodAsociacion = tCaPrestamos.CodAsociacion
) AND tCaProducto.Tecnologia = 3 AND tCaPrestamos.CodAsesor LIKE #CodAsesor AND tCaPrestamos.CodOficina IN (SELECT CodOficina FROM tClOficinas WHERE CodArbolConta LIKE #CodArbolConta)
UNION ALL
SELECT tClOficinas.CodOficina, tClOficinas.NomOficina, tCaClAsesores.CodAsesor, tCaClAsesores.NomAsesor, tCaHPrestamos.CodPrestamo, tCaAsociacion.CodAsociacion, tCaAsociacion.NombreAsociacion, tCaHPrestamos.Ciclo, tCaHPrCliente.CodUsuario, tCaHPrestamos.FechaEstado, tClParametros.FechaProceso FROM tCaHPrestamos WITH(NOLOCK) INNER JOIN tCaProducto WITH(NOLOCK) ON tCaProducto.CodProducto = tCaHPrestamos.CodProducto INNER JOIN tClOficinas WITH(NOLOCK) ON tClOficinas.CodOficina = tCaHPrestamos.CodOficina INNER JOIN tCaAsociacion WITH(NOLOCK) ON tCaAsociacion.CodAsociacion = tCaHPrestamos.CodAsociacion INNER JOIN tCaHPrCliente WITH(NOLOCK) ON tCaHPrCliente.CodPrestamo = tCaHPrestamos.CodPrestamo INNER JOIN tClParametros WITH(NOLOCK) ON tClParametros.CodOficina = tClOficinas.CodOficina INNER JOIN tCaClAsesores ON tCaClAsesores.CodAsesor = tCaAsociacion.CodAsesor WHERE tCaHPrestamos.Estado = 'CANCELADO' AND DATEDIFF(DAY, tCaHPrestamos.FechaEstado, tClParametros.FechaProceso) > 30 AND NOT EXISTS(SELECT 1
FROM tCaHPrestamos Pr
INNER JOIN tCaHPrCliente PrCl ON PrCl.CodPrestamo = Pr.CodPrestamo
WHERE Pr.Estado NOT IN ('TRAMITE', 'APROBADO')
AND Pr.FechaDesembolso >= tCaHPrestamos.FechaEstado
AND Pr.CodAsociacion = tCaHPrestamos.CodAsociacion
) AND tCaProducto.Tecnologia = 3 AND tCaHPrestamos.CodAsesor LIKE #CodAsesor AND tCaHPrestamos.CodOficina IN (SELECT CodOficina FROM tClOficinas WHERE CodArbolConta LIKE #CodArbolConta)
)tabACInactivas
GROUP BY tabACInactivas.CodAsociacion, tabACInactivas.NombreAsociacion, tabACInactivas.NomOficina, tabACInactivas.CodOficina, tabACInactivas.NomAsesor
I want the CantSocias column takes the most value of the Ciclo column, but not working
That stored procedure that you have posted up is way too large and blocky to even try to interpret and understand. So I will go off of your last sentence:
I want the CantSocias column takes the most value of the Ciclo column,
but not working
Basically if you want to set a specific column to that, you can do something like this:
update YourTable
set CantSocias =
(
select max(Ciclo)
from YourOtherTable
)
-- here is where you can put a conditional WHERE clause
You may need to create a sub query to get the most value of Ciclo and join back to your query.
An example of what I mean is here:
create table #Product
(
ID int,
ProductName varchar(20)
)
insert into #Product(ID, ProductName)
select 1,'ProductOne'
union
select 2,'ProductTwo'
create table #ProductSale
(
ProductID int,
Number int,
SalesRegion varchar(20)
)
insert into #ProductSale(ProductID,Number,SalesRegion)
select 1,1500,'North'
union
select 1, 1200, 'South'
union
select 2,2500,'North'
union
select 2, 3200, 'South'
--select product sales region with the most sales
select * from #Product p
select ProductId, Max(Number) as Bestsale from #ProductSale ps group by ProductID
--combining
select
p.ID,
p.ProductName,
tp.Bestsale,
ps.SalesRegion
from
#Product p
inner join
(select ProductId, Max(Number) as Bestsale from #ProductSale ps group by ProductID) as tp on p.ID = tp.ProductID
inner join
#ProductSale ps on p.ID = ps.ProductID and tp.Bestsale = ps.Number