I have this query:
Select b.building_pk, bil.building_fk, bil.BillingAccountStatus_fk, b.ACTL_TNT_CT
From [DB].[Schema].Building b (nolock)
left Join [DB].[Schema].Billing bil (nolock) on bil.building_fk = b.building_pk
join ##GlobalTempTable1 tt (nolock) on tt.Building_fk = b.building_pk
Order by b.building_pk;
It works fine. But I want to override NULLs in the result set in columns bil.building_fk and bil.BillingAccountStatus_fk as not everything in Billing tbl exists in building table.
So wrote the following query below, but getting this error message.
Msg 102, Level 15, State 1, Line 7 Incorrect syntax near '='.
Please assist.
SELECT b.building_pk, bil.building_fk As [BLD Key from Billing], bil.BillingAccountStatus_fk, b.ACTL_TNT_CT As [ActualTenantCount]
FROM [DB].[Schema].Building b (nolock)
join ##GlobalTempTable1 tt (nolock) ON tt.Building_fk = b.building_pk
left Join [DB].[Schema].Billing bil (nolock) ON
CASE
WHEN bil.building_fk IS NOT NULL
THEN bil.building_fk = b.building_pk AND bil.BillingAccountStatus_fk = bil.BillingAccountStatus_fk
WHEN bil.building_fk IS NULL
THEN bil.building_fk = NULL AND bil.BillingAccountStatus_fk = 'Not in Billing'
END
ORDER BY b.building_pk;
It's hard to tell what you are trying to do because it's very wrong. I think, though, that you want to keep your FROM the same and do the CASE statement up into the SELECT.
Select b.building_pk, CASE WHEN bil.Building_fk IS NULL THEN 'Not in Billing' ELSE bil.building_fk END as building_fk, bil.BillingAccountStatus_fk, b.ACTL_TNT_CT
From [DB].[Schema].Building b (nolock)
left Join [DB].[Schema].Billing bil (nolock) on bil.building_fk = b.building_pk
join ##GlobalTempTable1 tt (nolock) on tt.Building_fk = b.building_pk
Order by b.building_pk;
Or, better yet, use COALESCE() here:
Select b.building_pk, COALESCE(bil.Building_fk,'Not in Billing') as building_fk, bil.BillingAccountStatus_fk, b.ACTL_TNT_CT
From [DB].[Schema].Building b (nolock)
left Join [DB].[Schema].Billing bil (nolock) on bil.building_fk = b.building_pk
join ##GlobalTempTable1 tt (nolock) on tt.Building_fk = b.building_pk
Order by b.building_pk;
I am guessing that you are trying to do something like this:
SELECT b.building_pk, bil.building_fk As [BLD Key from Billing], bil.BillingAccountStatus_fk, b.ACTL_TNT_CT As [ActualTenantCount]
FROM [DB].[Schema].Building b (nolock)
join ##GlobalTempTable1 tt (nolock) ON tt.Building_fk = b.building_pk
left Join [DB].[Schema].Billing bil (nolock) ON
(bil.building_fk IS NOT NULL AND
(bil.building_fk = b.building_pk AND bil.BillingAccountStatus_fk = bil.BillingAccountStatus_fk))
OR (bil.building_fk IS NULL AND
(bil.building_fk = NULL AND bil.BillingAccountStatus_fk = 'Not in Billing'))
ORDER BY b.building_pk;
I'll leave the misguided use of nolock for another day ...
CASE expressions can't be used to set which criteria you use for a JOIN, they can be used on either side of the comparison operator in JOIN criteria, but I don't think you need that, I think you just need a LEFT JOIN and a COALESCE() in your SELECT:
SELECT b.building_pk
, bil.building_fk As [BLD Key from Billing]
, COALESCE(bil.BillingAccountStatus_fk,'Not in Billing')
, b.ACTL_TNT_CT As [ActualTenantCount]
FROM [DB].[Schema].Building b
join ##GlobalTempTable1 tt
ON tt.Building_fk = b.building_pk
left Join [DB].[Schema].Billing bil
ON bil.building_fk = b.building_pk
ORDER BY b.building_pk;
Edit: Noticed BillingAccountStatus_fk was coming from bil on both sides, so removed that from the JOIN criteria.
Related
I have this query in SQL Server, and i would like to know if it can be shorter ?
i've made a subquery (with a group by) with all the column just to get the MAX() value of 3 dates which come from a table left join.
Ithink i can't do without a subquery to get the MAX() of the 3 dates.
SELECT otherCol1
,otherCol2
,MAX(UnsubscribedDate) AS UnsubscribedDate
,MAX(OpenedDate) AS OpenedDate
,MAX(ClickedDate) AS ClickedDate
FROM (
SELECT otherCol1
,otherCol2
,tu.JoinDate AS UnsubscribedDate
,trkOp.Clicktime AS OpenedDate
,trkRes.Clicktime AS ClickedDate
FROM v_members_email_occurrence vmec
LEFT JOIN tracking_unsubscribed tu WITH (NOLOCK) ON tu.ReportId = vmec.SendingId
LEFT JOIN tracking_opened trkOp WITH (NOLOCK) ON trkOp.ReportId = vmec.SendingId
LEFT JOIN tracking_result trkRes WITH (NOLOCK) ON trkRes.ReportId = vmec.SendingId
WHERE vmec.MemberId = #MemberId
) AS Result
GROUP BY otherCol1
,otherCol2
You can aggregate without a subquery:
SELECT otherCol1
,otherCol2
,MAX(tu.JoinDate) AS UnsubscribedDate
,MAX(trkOp.Clicktime) AS OpenedDate
,MAX(trkRes.Clicktime) AS ClickedDate
FROM v_members_email_occurrence vmec
LEFT JOIN tracking_unsubscribed tu WITH (NOLOCK) ON tu.ReportId = vmec.SendingId
LEFT JOIN tracking_opened trkOp WITH (NOLOCK) ON trkOp.ReportId = vmec.SendingId
LEFT JOIN tracking_result trkRes WITH (NOLOCK) ON trkRes.ReportId = vmec.SendingId
WHERE vmec.MemberId = #MemberId
GROUP BY otherCol1
,otherCol2
Good Afternoon,
I currently have the query:
SELECT erp_user.login,
SUM(invoice_header.invoice_amount) as 'Invoices Billed'
FROM erp_user
LEFT JOIN order_header ON erp_user.erp_user_id = order_header.req_by
LEFT JOIN invoice_instruct_header ON order_header.order_id = invoice_instruct_header.order_id
LEFT JOIN invoice_header ON invoice_instruct_header.instruct_id = invoice_header.instruct_no
WHERE erp_user.supervisor_id IS NOT NULL AND user_id_type = 'I' AND erp_user.company_id IS NOT NULL AND erp_user.is_active = 1
GROUP BY erp_user.login
It gives me a list of total billing in our system by employee where the employee is signed to a job on the job header.
I would love to add the total amount of open PO's to this query so I added:
SELECT erp_user.login, SUM(invoice_header.invoice_amount) as 'Invoices Billed', sum(po_header.po_amount) AS "Open PO's"
FROM erp_user
LEFT JOIN order_header ON erp_user.erp_user_id = order_header.req_by
LEFT JOIN invoice_instruct_header ON order_header.order_id = invoice_instruct_header.order_id
LEFT JOIN invoice_header ON invoice_instruct_header.instruct_id = invoice_header.instruct_no
LEFT JOIN po_header ON order_header.order_id = po_header.order_id
WHERE erp_user.supervisor_id IS NOT NULL AND user_id_type = 'I' AND erp_user.company_id IS NOT NULL AND erp_user.is_active = 1 AND po_header.status = 1
GROUP BY erp_user.login
ORDER BY "Open PO's"
That query gives me numbers in my Open PO's column, but they are incorrect and I'm at the point now where I can't figure out how to troubleshoot this.
Can someone please point me in the right direction? I don't mind doing the work, just need a pointer. Thanks!
Please be aware of conbination of Left join and Where clause.
SELECT erp_user.login
, SUM(invoice_header.invoice_amount) as 'Invoices Billed'
, sum(CASE WHEN po_header.status = 1 THEN po_header.po_amount ELSE 0 END) AS "Open PO's"
FROM erp_user
LEFT JOIN order_header ON erp_user.erp_user_id = order_header.req_by
LEFT JOIN invoice_instruct_header ON order_header.order_id = invoice_instruct_header.order_id
LEFT JOIN invoice_header ON invoice_instruct_header.instruct_id = invoice_header.instruct_no
LEFT JOIN po_header ON order_header.order_id = po_header.order_id
WHERE erp_user.supervisor_id IS NOT NULL
AND user_id_type = 'I'
AND erp_user.company_id IS NOT NULL
AND erp_user.is_active = 1
GROUP BY erp_user.login
ORDER BY "Open PO's";
If po_header joins to order_header, then in your original query it would be repeating each po_header for each invoice_header as well (leading to the incorrect calculation).
You could use outer apply() like so:
select
erp_user.login
, [Invoices Billed] = sum(invoice_header.invoice_amount)
, x.[Open POs]
from erp_user
left join order_header
on erp_user.erp_user_id = order_header.req_by
left join invoice_instruct_header
on order_header.order_id = invoice_instruct_header.order_id
left join invoice_header
on invoice_instruct_header.instruct_id = invoice_header.instruct_no
outer apply (
select
[Open POs] = sum(po_header.po_amount)
from po_header p
inner join order_header oh
on oh.order_id = p.order_id
where oh.req_by = erp_user.erp_user_id
) x
where erp_user.supervisor_id is not null
and erp_user.company_id is not null
and erp_user.is_active = 1
and user_id_type = 'I'
group by erp_user.login
Looks that I am stumped with query to sum up shipments grouped by by union operator. Today I was working to retrieve total shipments (count(Distinct. U.SjipmentId) delivered by agent, driver (U.AgentCode) to particular country (U.CtryCode, U.CtryName). The last thing I would like to do is to sum all the shipments together to get the total amount of shipments.
Would anyone advise how I this can be achieved in easy and simply way?
Below you can find my most current query.
SELECT U.AgentCode, U.CtryCode, U.CtryName, count(distinct U.Id)
FROM (
select Agent.AgentCode, Addr.CtryCode, Ctry.Name, Ship.Id
from Shipment
LEFT JOIN RouteTab (nolock) ON RoutTbl.Cexp= Shipment.ID
LEFT JOIN Agent (NOLOCK) ON Agent.AgentID = RouteTbl.AgentID
LEFT JOIN Addr (NOLOCK) ON Addr.AddrId = Shipment.AddrId
LEFT JOIN Ctry (NOLOCK) ON Ctry.Id = Addr.Id
WHERE RouteTbl.Bur ='GB01' AND Agent.AgentCode IS NOT NULL
Union ALL
select Driver.DriverCode, Addr.CtryCode, Ctry.Name, Shipment.Id
from Shipment
LEFT JOIN RouteTab (nolock) ON RoutTbl.Cexp= Shipment.Id
LEFT JOIN Driver (NOLOCK) ON Driver.DriverId = RouteTbl.DriverId
LEFT JOIN Addr (NOLOCK) ON Addr.AddrId = Shipment.AddrId
LEFT JOIN Ctry (NOLOCK) ON Ctry.Id = Addr.Id
WHERE RouteTbl.Bur ='GB01' AND Driver.DriverCode IS NOT NULL
) as U
GROUP BY U.AgentCode, U.CtryCode, U.CtryName
ORDER BY U.AgentCode, U.CtryCode, U.CtryName
Union statements need to have the exact same column names, in your code below the Union All command, try this:
select Driver.DriverCode as AgentCode, Addr.CtryCode, Ctry.Name, Shipment.Id
Also change the Ctry.Name to Ctry.Name as CtryName in both your select statements.
You have the same code from your UNION. Good way to use WITH clause.
In your select you don't need a UNION - use a left join and COALESCE instead.
;With r_tab AS
(
select RouteTab.AgentID, Addr.CtryCode, Ctry.Name, Ship.Id,RouteTab.DriverId
from Shipment
LEFT JOIN RouteTab (nolock) ON RouteTab.Cexp= Shipment.ID
LEFT JOIN Addr (NOLOCK) ON Addr.AddrId = Shipment.AddrId
LEFT JOIN Ctry (NOLOCK) ON Ctry.Id = Addr.Id
WHERE RouteTab.Bur ='GB01'
)
SELECT COALESCE(Agent.AgentCode,Driver.DriverCode) AgentCode, U.AgentCode, U.CtryCode, U.CtryName,
count(distinct U.Id)
FROM r_tab U
LEFT JOIN Agent (NOLOCK) ON Agent.AgentID = U.AgentID
AND Agent.AgentCode IS NOT NULL
LEFT JOIN Driver (NOLOCK) ON Driver.DriverId = U.DriverId
AND Driver.DriverCode IS NOT NULL
GROUP BY COALESCE(Agent.AgentCode,Driver.DriverCode), U.CtryCode, U.CtryName
ORDER BY U.AgentCode, U.CtryCode, U.CtryName`enter code here`
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/
is there any way that i can restructure this below query without using intersect. Because using intersect causing very slow performance. Please suggest
SELECT DISTINCT( PFM.id ) AS PfmFolderFK
FROM cm.pfmfolder PFM WITH(nolock)
INNER JOIN cm.pfmfoldermstipmap PFMMST WITH(nolock)
ON PFMMST.pfmfolderfk = PFM.id
INNER JOIN cm.mstip MST WITH(nolock)
ON MST.id = PFMMST.mstipfk
WHERE MST.registrycode = #RegistryCode
AND PFM.deletedby IS NULL
AND PFM.deleteddate IS NULL
INTERSECT
SELECT DISTINCT( FMAP.pfmfolderfk ) AS PfmFolderFK
FROM cm.mstip MIP WITH(nolock)
INNER JOIN cm.pfmfoldermstipmap FMAP WITH(nolock)
ON MIP.id = FMAP.mstipfk
AND MIP.registrycode = #RegistryCode
AND MIP.deletedby IS NULL
AND MIP.deletedate IS NULL
An intersect is taking values from both tables. The queries are quite similar here, so I think you just need an additional join in the first table to complete the logic without an intersect:
SELECT DISTINCT( PFM.id ) AS PfmFolderFK
FROM cm.pfmfolder PFM WITH(nolock) INNER JOIN
cm.pfmfoldermstipmap PFMMST WITH(nolock)
ON PFMMST.pfmfolderfk = PFM.id INNER JOIN
cm.mstip MST WITH(nolock)
ON MST.id = PFMMST.mstipfk INNER JOIN
cm.pfmfoldermstipmap FMAP WITH(nolock)
ON PFMMST.id = FMAP.mstipfk AND
PFMMST.registrycode = #RegistryCode AND
PFMMST.deletedby IS NULL AND
PFMMST.deletedate IS NULL
WHERE MST.registrycode = #RegistryCode AND
PFM.deletedby IS NULL AND
PFM.deleteddate IS NULL;
How about this? I think you need to take only the first part of your query and add two contitions to it.
SELECT DISTINCT FMAP.pfmfolderfk AS PfmFolderFK
FROM cm.mstip MST WITH(nolock)
INNER JOIN cm.pfmfoldermstipmap FMAP WITH(nolock) ON MST.id = FMAP.mstipfk
INNER JOIN cm.pfmfolder PFM WITH(nolock) ON FMAP.pfmfolderfk = PFM.id
WHERE MST.registrycode = #RegistryCode
AND PFM.deletedby IS NULL
AND PFM.deleteddate IS NULL
AND MST.deletedby IS NULL
AND MST.deletedate IS NULL
Queries with DISTINCT are always dubious ;-) You are looking for pfmfolders where certain records exist in pfmfoldermstipmap and mstip. Use EXISTS for that. Actually you are looking for all pfmfolders that are in pfmfoldermstipmap and mstip and are either not deleted themselves or having not deleted mstips:
select id
from cm.pfmfolder
where exists
(
select *
from cm.pfmfoldermstipmap
inner join cm.mstip on mstip.id = pfmfoldermstipmap.mstipfk
and pfmfoldermstipmap.pfmfolderfk = pfmfolder.id
and mstip.registrycode = #registrycode
and
(
(pfmfolder.deletedby is null and pfmfolder.deleteddate is null)
or
(mstip.deletedby is null and mstip.deleteddate is null)
)
);