SQL stored procedure Join question - sql-server-2005

currently the stored proc returns one record based on a employee_number that is passed as a parameter. If the surpervisor_id is NULL, there is no record returned. If I want to return a record with all the other fields, and have a NULL in the supervisor_id field, how would I configure that?
SELECT DISTINCT
tblPeople.PERSON_ID, tblPeople.FIRST_NAME, tblPeople.LAST_NAME,
tblPeople.EMPLOYEE_NUMBER, tblPeople.EMAIL_ADDRESS,
tblAddress.ADDRESS_LINE1, tblAddress.ADDRESS_LINE2, tblAddress.ADDRESS_LINE3,
tblAddress.TOWN_OR_CITY, tblAddress.STATE, tblAddress.COUNTRY,
tblAddress.POSTAL_CODE, tblPeople.PHONE_NUMBER,
tblPeople.EFFECTIVE_START_DATE, tblPeople.EFFECTIVE_END_DATE,
tblLocation.LOC_CODE,
pp2.FIRST_NAME AS Expr1, pp2.LAST_NAME AS Expr2,
pp2.EMPLOYEE_NUMBER AS Expr3, tblAssignment.SUPERVISOR_ID,
tblAssignment.ATTRIBUTE2, tblAssignment.ATTRIBUTE3,
tblPeople.INSTANCE_ID, tblAssignment.LOC_ID
FROM
tblPeople AS tblPeople
RIGHT OUTER JOIN
tblAddress AS tblAddress ON tblPeople.PERSON_ID = tblAddress.PERSON_ID
AND tblPeople.INSTANCE_ID = tblAddress.INSTANCE_ID
INNER JOIN
tblAssignments AS tblAssignment ON tblPeople.PERSON_ID = tblAssignment.PERSON_ID
AND tblPeople.INSTANCE_ID = tblAssignment.INSTANCE_ID
INNER JOIN
Locations AS Location ON Location.LOC_ID = tblAssignment.LOC_ID
AND Location.INSTANCE_ID = tblAssignment.INSTANCE_ID
INNER JOIN
tblPeople AS pp2 ON pp2.PERSON_ID = tblAssignment.SUPERVISOR_ID
AND pp2.INSTANCE_ID = tblAssignment.INSTANCE_ID
WHERE
tblPeople.EMPLOYEE_NUMBER = '3298'
AND tblPeople.INSTANCE_ID = 1
AND tblAssignment.Assignment_Status = 'Current'

Most likely, you just need to change this JOIN
INNER JOIN
tblPeople AS pp2 ON pp2.PERSON_ID = tblAssignment.SUPERVISOR_ID
AND pp2.INSTANCE_ID = tblAssignment.INSTANCE_ID
to an LEFT OUTER JOIN
LEFT OUTER JOIN
tblPeople AS pp2 ON pp2.PERSON_ID = tblAssignment.SUPERVISOR_ID
AND pp2.INSTANCE_ID = tblAssignment.INSTANCE_ID
If that SUPERVISOR_ID IS NULL, then the columns from the pp2 table will be NULL, but you should still get data for all other columns back.

Related

How to display data from 4 different tables - Query Designer

I need to build my query using SQL Server Management Studio Query Designer
I need to display a concatenated string of tbl_B.Name + tbl_C.Name + tbl_D.Name, if Id in tbl_E/tbl_User is equal to UserId in tbl_A
This is the Table structure https://imgur.com/PZagLPq, https://imgur.com/moE4dcf
tbl_A UserId = Id in tbl_E/tbl_User
tbl_B_Id = Id in tbl_B
tbl_C_Id = Id in tbl_C
tbl_D_Id = Id in tbl_D
I tried the below code but doesn't display Name field from tbl_B, tbl_C and tbl_D
SELECT tbl_B.Name AS Expr1, tbl_C.Name AS Expr2, tbl_D.Name AS Expr3, tbl_A.UserId, [tbl_E].Id AS Expr5
FROM tbl_B
INNER JOIN tbl_D ON tbl_B.Id = tbl_D.Id
INNER JOIN tbl_A ON tbl_B.Id = tbl_A.Id
INNER JOIN tbl_C ON tbl_B.tbl_CId = tbl_C.Id AND tbl_D.Id = tbl_C.tbl_DId
INNER JOIN [tbl_E] ON tbl_B.Id = [tbl_E].Id AND tbl_A.UserId = [tbl_E].Id
WHERE (tbl_A.UserId = [tbl_E].Id)
Below query will give you the concatenated string of names for every userId, which has entry in all the tables.
SELECT
"tbl_A"."UserId",
CONCAT("tbl_B"."Name", '-', "tbl_C"."Name", '-', "tbl_D"."Name"),
"tbl_B"."Name" AS Expr1,
"tbl_C"."Name" AS Expr2,
"tbl_D"."Name" AS Expr3
FROM "tbl_E"
INNER JOIN "tbl_A" ON "tbl_A"."UserId" = "tbl_E"."id"
INNER JOIN "tbl_B" ON "tbl_B"."id" = "tbl_A"."tbl_B_id"
INNER JOIN "tbl_C" ON "tbl_C"."id" = "tbl_B"."tbl_C_id"
INNER JOIN "tbl_D" ON "tbl_D"."id" = "tbl_C"."tbl_D_id"

Getting extra Row containing Null Value for specific Names

In my Query if CompanyName has Coamount = NULL then Final should be as of Contract amount. If CompanyName has Coamount then Final would be ContractAmount + Coamount.
I am getting all these answers but the query is also returning me rows which has NULL value in Coamount for those company name in which coamount is already present.
for eg: Row1, why is that row coming when I am getting row 2 as my answer according to my query.
Here is the code:
SELECT DISTINCT
HBRegions.RegionName,PropertyGroups.Name AS Owner,Properties.EntityID, Properties.Address,Vendors.CompanyName,
SubContractorDrawDetails.InvoiceUploadDate,SubContractorDrawDetails.InvoiceAmount,SubContractorDrawDetails.PaymentDate,
LienWaivers.FinalLienWaiverRcvdDate,SubContractorDrawDetails.PaymentAmount, subcontractors.ContractAmount,cc.Coamount ,
(subcontractors.ContractAmount + cc.Coamount ) AS ActualContractAmount,
case when cc.Coamount is null then SubContractors.ContractAmount
when CC.Coamount is not null then (subcontractors.ContractAmount + cc.Coamount ) end as Final
FROM Users inner JOIN
Vendors ON Users.UserId = Vendors.UserID inner JOIN
LienWaivers ON Users.UserId = LienWaivers.UserID inner JOIN
Constructions ON LienWaivers.ConstructionID = Constructions.ConstructionId inner JOIN
Properties ON Constructions.HBId = Properties.HBId inner JOIN
ChangeOrderDetails ON Constructions.ConstructionId = ChangeOrderDetails.ConstructionId left JOIN
ChangeOrderLineItems ON Users.UserId = ChangeOrderLineItems.SubContractorId AND
ChangeOrderDetails.ChangeOrderId = ChangeOrderLineItems.ChangeOrderId
left join
(select sum(ChangeOrderDetails.ChangeOrderApprovedAmountContractor) as Coamount, ChangeOrderLineItems.SubContractorId,Constructions.ConstructionId
from ChangeOrderDetails inner join ChangeOrderLineItems
on ChangeOrderDetails.ChangeOrderId = ChangeOrderLineItems.ChangeOrderId
inner join Users on ChangeOrderLineItems.SubContractorId = Users.UserId
left join Constructions on Constructions.ConstructionId = ChangeOrderDetails.ConstructionId
-- left join Properties on Properties.HBId = Constructions.HBId
where ChangeOrderDetails.ChangeOrderApprovedAmountContractor is not null
group by ChangeOrderLineItems.SubContractorId,Constructions.ConstructionId
) AS cc on cc.SubContractorId = ChangeOrderLineItems.SubContractorId and cc.ConstructionId = Constructions.ConstructionId
inner join HBRegions ON Properties.RegionId = HBRegions.RegionID inner JOIN
PropertyGroups ON Properties.PropertyGroup = PropertyGroups.PropertyGroupId
inner join SubContractors ON Users.UserId = SubContractors.UserID AND Properties.HBId = SubContractors.HBId
inner join SubContractorDrawDetails ON SubContractors.SubContractorId = SubContractorDrawDetails.SubContractorId
WHERE (Properties.Address = '470 ROYCROFT BLVD BUFFALO NY 14225')[enter image description here][1]

using a subquery as a column that's using another column in the 'where' clause

I probably messed that title up! So I have a column called "programID" and I want another column to tell me the most recent date an order was placed using the programID. I think I'd need a subcolumn but the problem is how do I use the row's programID so that it matches the programID for the same row?
DECLARE #ClientIDs varchar(4) = 6653;
DECLARE #ProgramStatus char(1) = 'Y'; -- Y, N, or R
SELECT
rcp.RCPID AS ProgramID
, rcp.RCPName AS Program
, rcp.RCPActive AS ProgramStatus
, aa.AACustomCardInternalReview AS VCCP
, aa.AAJobNo AS AAJobNo
, aas.AASName AS AAStatus
, rcp.RCPOpsApproved AS OpsApproved
, clt.CltID AS ClientID
, rcp.RCPSignatureRequired AS SignatureRequired
, st.STEnumValue AS DefaultShipType
, rcp.RCPShipMethodOverrideType AS ShipTypeOverride
,aa.AANetworkProgramID
,(Select max(cdconfirmationdate) from carddet where ) --can't figure this part out
FROM
RetailerCardProgram rcp WITH (NOLOCK)
INNER JOIN ClientRetailerMap crm WITH (NOLOCK)
ON crm.CRMRetailerID = rcp.RCPRetailerID
INNER JOIN Client clt WITH(NOLOCK)
ON clt.CltID = crm.CRMCltID
LEFT JOIN AssociationApproval aa WITH (NOLOCK)
ON aa.AARetailerID = rcp.RCPRetailerID
AND aa.AABin = rcp.RCPBin6
AND aa.AAFrontOfPlasticTemplateID = rcp.RCPFOCTemplateID
AND aa.AABackOfPlasticTemplateID = rcp.RCPBOCTemplateID
AND ISNULL(aa.AACardID, 0) = ISNULL(rcp.RCPDefaultPlasticCardID, 0)
-- AND LOWER(rcp.RCPName) NOT LIKE '%do not use%' -- Needed for AA Job Number 1594
LEFT JOIN AssociationApprovalStatus aas WITH (NOLOCK)
ON aas.AASID = aa.AAAssociationApprovalStatusID
LEFT JOIN OpenLoopAssociation ola WITH (NOLOCK)
ON ola.OLAID=rcp.RCPOLAID
LEFT JOIN ClientCardProgramMap ccpm WITH (NOLOCK)
ON ccpm.CCPMCardProgramID = rcp.RCPID
AND ccpm.CCPMClientID = clt.CltID
LEFT JOIN TippingModule tm WITH (NOLOCK)
ON tm.TMid = rcp.RCPTippingModuleID
LEFT JOIN GiftCardTemplate fgt WITH (NOLOCK)
ON fgt.gtid = rcp.RCPFOCTemplateID
AND fgt.GTPage='P'
LEFT JOIN GiftCardTemplate bgt WITH (NOLOCK)
ON bgt.gtid = rcp.RCPBOCTemplateID
AND bgt.GTPage='PB'
LEFT JOIN Card c WITH (NOLOCK)
ON c.CardID = rcp.RCPDefaultCarrierID
LEFT JOIN CardType ct WITH (NOLOCK)
ON ct.CTID = c.CardTypeID
LEFT JOIN RetailerCardProgramTCSheetMap rtm1 WITH (NOLOCK)
ON rtm1.RTMRCPID = rcp.RCPID
AND rtm1.RTMInsertOrder = 1
LEFT JOIN RetailerCardProgramTCSheetMap rtm2 WITH (NOLOCK)
ON rtm2.RTMRCPID = rcp.RCPID
AND rtm2.RTMInsertOrder = 2
LEFT JOIN RetailerCardProgramTCSheetMap rtm3 WITH (NOLOCK)
ON rtm3.RTMRCPID = rcp.RCPID
AND rtm3.RTMInsertOrder = 3
LEFT JOIN RetailerCardProgramTCSheetMap rtm4 WITH (NOLOCK)
ON rtm4.RTMRCPID = rcp.RCPID
AND rtm4.RTMInsertOrder = 4
LEFT JOIN TCSheet i1 WITH (NOLOCK)
ON i1.TCSID = rtm1.RTMTCSID
LEFT JOIN TCSheet i2 WITH (NOLOCK)
ON i2.TCSID = rtm2.RTMTCSID
LEFT JOIN TCSheet i3 WITH (NOLOCK)
ON i3.TCSID = rtm3.RTMTCSID
LEFT JOIN TCSheet i4 WITH (NOLOCK)
ON i4.TCSID = rtm4.RTMTCSID
LEFT JOIN ShipType st WITH (NOLOCK)
ON st.STId = rcp.RCPDefaultShipTypeID
WHERE
clt.CltID IN (#ClientIDs) -- 6653 and 6657.
AND rcp.RCPActive IN (#ProgramStatus)
ORDER BY
AAJobNo
, Program
You want to join with a nested select on the table carddet. I'm inferring that RCPID is the relationship between carddet and your main table RetainerCardProgram...
SELECT rcp.RCPID AS ProgramID,
date.MAXDATE AS MaxDate,
rest of your columns...
FROM RetailerCardProgram rcp WITH (NOLOCK)
INNER JOIN (
SELECT RCPID, MAX(cdconfirmationdate) as 'MAXDATE'
FROM carddet
GROUP BY RCPID
) date on date.RCPID = rcp.RCPID
rest of query...
You may want a left join if not all IDs have a date in carddet.
Obligatory addition: Also your use of NOLOCK is a bit terrifying. See http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/

How to use group by only for some columns in sql Query?

The following query returns 550 records, which I am then grouping by some columns in the controller via linq. However, how can I achieve the "group by" logic in the SQL query itself? Additionally, post-grouping, I need to show only 150 results to the user.
Current SQL query:
SELECT DISTINCT
l.Id AS LoadId
, l.LoadTrackingNumber AS LoadDisplayId
, planningType.Text AS PlanningType
, loadStatus.Id AS StatusId
, loadWorkRequest.Id AS LoadRequestId
, loadStatus.Text AS Status
, routeIds.RouteIdentifier AS RouteName
, planRequest.Id AS PlanId
, originPartyRole.Id AS OriginId
, originParty.Id AS OriginPartyId
, originParty.LegalName AS Origin
, destinationPartyRole.Id AS DestinationId
, destinationParty.Id AS DestinationPartyId
, destinationParty.LegalName AS Destination
, COALESCE(firstSegmentLocation.Window_Start, originLocation.Window_Start) AS StartDate
, COALESCE(firstSegmentLocation.Window_Start, originLocation.Window_Start) AS BeginDate
, destLocation.Window_Finish AS EndDate
AS Number
FROM Domain.Loads (NOLOCK) AS l
INNER JOIN dbo.Lists (NOLOCK) AS loadStatus ON l.LoadStatusId = loadStatus.Id
INNER JOIN Domain.Routes (NOLOCK) AS routeIds ON routeIds.Id = l.RouteId
INNER JOIN Domain.BaseRequests (NOLOCK) AS loadWorkRequest ON loadWorkRequest.LoadId = l.Id
INNER JOIN Domain.BaseRequests (NOLOCK) AS planRequest ON planRequest.Id = loadWorkRequest.ParentWorkRequestId
INNER JOIN Domain.Schedules AS planSchedule ON planSchedule.Id = planRequest.ScheduleId
INNER JOIN Domain.Segments (NOLOCK) os on os.RouteId = routeIds.Id AND os.[Order] = 0
INNER JOIN Domain.LocationDetails (NOLOCK) AS originLocation ON originLocation.Id = os.DestinationId
INNER JOIN dbo.EntityRoles (NOLOCK) AS originPartyRole ON originPartyRole.Id = originLocation.DockRoleId
INNER JOIN dbo.Entities (NOLOCK) AS originParty ON originParty.Id = originPartyRole.PartyId
INNER JOIN Domain.LocationDetails (NOLOCK) AS destLocation ON destLocation.Id = routeIds.DestinationFacilityLocationId
INNER JOIN dbo.EntityRoles (NOLOCK) AS destinationPartyRole ON destinationPartyRole.Id = destLocation.DockRoleId
INNER JOIN dbo.Entities (NOLOCK) AS destinationParty ON destinationParty.Id = destinationPartyRole.PartyId
INNER JOIN dbo.TransportationModes (NOLOCK) lictm on lictm.Id = l.LoadInstanceCarrierModeId
INNER JOIN dbo.EntityRoles (NOLOCK) AS carrierPartyRole ON lictm.CarrierId = carrierPartyRole.Id
INNER JOIN dbo.Entities (NOLOCK) AS carrier ON carrierPartyRole.PartyId = carrier.Id
INNER JOIN dbo.EntityRoles (NOLOCK) AS respPartyRole ON l.ResponsiblePartyId = respPartyRole.Id
INNER JOIN dbo.Entities (NOLOCK) AS respParty ON respPartyRole.PartyId = respParty.Id
INNER JOIN Domain.LoadOrders (NOLOCK) lo ON lo.LoadInstanceId = l.Id
INNER JOIN Domain.Orders (NOLOCK) AS o ON lo.OrderInstanceId = o.Id
INNER JOIN Domain.BaseRequests (NOLOCK) AS loadRequest ON loadRequest.LoadId = l.Id
--Load Start Date
LEFT JOIN Domain.Segments (NOLOCK) AS segment ON segment.RouteId = l.RouteId AND segment.[Order] = 0
LEFT JOIN Domain.LocationDetails (NOLOCK) AS firstSegmentLocation ON firstSegmentLocation.Id = segment.DestinationId
LEFT JOIN dbo.Lists (NOLOCK) AS planningType ON l.PlanningTypeId = planningType.Id
LEFT JOIN dbo.EntityRoles (NOLOCK) AS billToRole ON o.BillToId = billToRole.Id
LEFT JOIN dbo.Entities (NOLOCK) AS billTo ON billToRole.PartyId = billTo.Id
WHERE o.CustomerId in (34236) AND originLocation.Window_Start >= '07/19/2015 00:00:00' AND originLocation.Window_Start < '07/25/2015 23:59:59' AND l.IsHistoricalLoad = 0
AND loadStatus.Id in (285, 286,289,611,290)
AND loadWorkRequest.ParentWorkRequestId IS NOT NULL
AND routeIds.RouteIdentifier IS NOT NULL
AND (planSchedule.EndDate IS NULL OR (planSchedule.EndDate is not null and CAST(CONVERT(varchar(10), planSchedule.EndDate,101) as datetime) > CAST(CONVERT(varchar(10),GETDATE(),101) as datetime))) ORDER BY l.Id DESC
linq:
//Get custom grouped data
var loadRequest = (from lq in returnList
let loadDisplayId = lq.LoadDisplayId
let origin = lq.OriginId //get this origin for route
let destination = lq.DestinationId // get this destination for route
group lq by new
{
RouteId = lq.RouteName,
PlanId = lq.PlanId,
Origin = lq.OriginId,
Destination = lq.DestinationId
}
into grp
select new
{
RouteId = grp.Key.RouteId,
PlanId = grp.Key.PlanId,
Origin = grp.Key.Origin,
Destination = grp.Key.Destination,
Loads = (from l in grp select l)
}).OrderBy(x => x.Origin).ToList();
I'm guessing you want to Group By column 1 but include columns 2 and 3 in your Select. Using a Group By you cannot do this. However, you can do this using a T-SQL Windowing function using the OVER() operator. Since you don't say how you want to aggregate, I cannot provide an example. But look at T-SQL Windowing functions. This article might help you get started.
One important thing you need to understand about GROUP BY is that you must assume that there are multiple values in every column outside of the GROUP BY list. In your case, you must assume that for each value of Column1 there would be multiple values of Column2 and Column3, all considered as a single group.
If you want your query to process any of these columns, you must specify what to do about these multiple values.
Here are some choices you have:
Pick the smallest or the largest value for a column in a group - use MIN(...) or MAX(...) aggregator for that
Count non-NULL items in a group - use COUNT(...)
Produce an average of non-NULL values in a group - use AVG(...)
For example, if you would like to find the smallest Column2 and an average of Column3 for each value of Column1, your query would look like this:
select
Column1, MIN(Column2), AVG(Column3)
from
TableName
group by
Column1

Why query with MAX(Date) dosen't return any record?

I have a sql query like below:
SELECT CPH.CheckPointID,
CPH.ID AS Check_Point_History_ID,
CLCP.SequenceNo AS Sequence,
CP.Code AS Point_Code,
CPV.ID,
TT.Medium AS Description,
[TEXT_TRANSLATION_ANS].[Medium] AS Value,
CPH.Value_ AS Additional_Information,
EMP.NAME AS Checked_By,
CPH.AnsweredOn AS Checked_On
FROM CHECK_LIST_HISTORY CLH
LEFT JOIN CHECK_POINT_HISTORY CPH
ON CLH.ID = CPH.CheckListHistoryID
INNER JOIN (
SELECT CPH2.CheckPointID,
MAX(CPH2.AnsweredOn) AS MaxDate
FROM CHECK_LIST_HISTORY CLH2
LEFT JOIN CHECK_POINT_HISTORY CPH2
ON CLH2.ID = CPH2.CheckListHistoryID
GROUP BY CPH2.CheckPointID
) tm
ON CPH.CheckPointID = tm.CheckPointID
AND CPH.AnsweredOn = tm.MaxDate
LEFT JOIN CHECK_POINT CP
ON CPH.CheckPointID = CP.ID
LEFT JOIN CHECK_POINT_VALUE CPV
ON CPH.CheckPointValueID = CPV.ID
LEFT JOIN TEXT_TRANSLATION TT
ON CP.TextID = TT.TextID
AND TT.LanguageID = LanguageID
LEFT JOIN CHECK_LIST_CHECK_POINT CLCP
ON CP.ID = CLCP.CheckPointID
LEFT JOIN EMPLOYEE EMP
ON CPH.EmployeeID = EMP.ID
LEFT JOIN [TEXT_TRANSLATION] [TEXT_TRANSLATION_ANS]
ON CPV.AnswerTextID = [TEXT_TRANSLATION_ANS].[TextID]
AND [TEXT_TRANSLATION_ANS].[LanguageID] = TT.LanguageID
LEFT JOIN [TEXT_TRANSLATION] [TEXT_TRANSLATION_RES]
ON CPV.ResponseTextID = [TEXT_TRANSLATION_RES].[TextID]
AND [TEXT_TRANSLATION_RES].[LanguageID] = TT.LanguageID
WHERE CLH.WipOrderNo = 304
AND CLH.WipOrderType = 26
AND CLCP.WorkCenter = 'WC03'
AND CLCP.Facility = 'C1P1'
This query should return me two records with maximum date, but it returns nothing. I think the problem is in the INNER JOIN because when the line with the INNER JOIN is commented, the query returns the following table: