SQL JOIN with a condition - sql

I am using SQL SERVER 2008 R2.
My query join is like this:
SELECT dbo.TARIF_COURANT.CODE_TARIF,
dbo.TARIF_COURANT.NO_CLIENT,dbo.TARIF_COURANT.ZONE, dbo.TARIF_COURANT.UNITE,
dbo.TARIF_COURANT.LIBELLE, dbo.TARIF_COURANT.TR_DEB, dbo.TARIF_COURANT.TR_FIN,
dbo.TARIF_COURANT.MONTANT,dbo.T_TARIF_ZONE.LIBELLE AS ZONELIB,
dbo.T_TARIF_ZONE.DEPARTEMENT, dbo.T_TARIF_ZONE.DELAI
FROM dbo.TARIF_COURANT LEFT OUTER JOIN dbo.T_TARIF_ZONE ON
dbo.TARIF_COURANT.ZONE = dbo.T_TARIF_ZONE.NO_ID
WHERE (dbo.TARIF_COURANT.TEMPO = 2) AND
(dbo.TARIF_COURANT.ZONE IN (1, 2, 3, 4, 6))
ORDER BY dbo.TARIF_COURANT.TR_DEB
Now i add another table LS_CLIENT_DEPT, and i modify my join:
SELECT dbo.TARIF_COURANT.CODE_TARIF, dbo.TARIF_COURANT.NO_CLIENT,
dbo.TARIF_COURANT.ZONE, dbo.TARIF_COURANT.UNITE, dbo.TARIF_COURANT.LIBELLE,
dbo.TARIF_COURANT.TR_DEB, dbo.TARIF_COURANT.TR_FIN, dbo.TARIF_COURANT.MONTANT,
dbo.T_TARIF_ZONE.LIBELLE AS ZONELIB, dbo.LS_CLIENT_DEPT.DEPARTEMENT,
dbo.T_TARIF_ZONE.DELAI
FROM dbo.TARIF_COURANT LEFT OUTER JOIN dbo.T_TARIF_ZONE ON
dbo.TARIF_COURANT.ZONE = dbo.T_TARIF_ZONE.NO_ID
LEFT OUTER JOIN dbo.LS_CLIENT_DEPT ON dbo.TARIF_COURANT.NO_CLIENT =
dbo.LS_CLIENT_DEPT.CODE_CLIENT AND dbo.TARIF_COURANT.ZONE =
dbo.LS_CLIENT_DEPT.ZONE
WHERE (dbo.TARIF_COURANT.TEMPO = 2) AND (dbo.TARIF_COURANT.ZONE IN (1, 2, 3,
4, 6)) ORDER BY dbo.TARIF_COURANT.TR_DEB
The object is if the column DEPARTEMENT in table 'LS_CLIENT_DEPT' is 'NOT NULL' then use this column value else use the column DEPARTEMENT value from table 'T_TARIF_ZONE'
Thanks you in advance

Sounds like you want:
COALESCE(LS_CLIENT_DEPT.DEPARTEMENT, T_TARIF_ZONE.DEPARTEMENT)
So it will take Department from LS_Client_Dept if it isn't null, and if it is null, return Department from T_TARIF_ZONE instead (this could be null too, however).
MSDN Documentation on Coalesce.

Related

How to default to a value in SQL to use for a join if conditions aren't met

I hope I can explain this clearly.
I have a four digit NAICS code lookup table that I am trying to join some records to. The root table has a six-digit NAICS code that I trim and compare to the table (emd) that I want to join to. There are three conditions that I want to join to emd on:
State from root table (x) matches emd
The year in the emd table is the max year in emd for that state
The NAICS code in table x matches the NAICS code in table emd
WHEN #3 is not met, I want the query to use '0000' as the NAICS code.
I.E. - If a record from table X with NAICS "6242" and State "AZ" exists, but table emd doesn't have a corresponding row for "AZ' with "6242", I want to use the "AZ" row with "0000".
I will paste the query below. To initially get this to kind of work, on the join to table emd, I added a case statement, basically saying "If the NAICS codes match, use it. Otherwise, use "0000". However, that is creating duplication.
When I test the query and run a query for a state that does have a NAICS code in the table (not 0000), it still returns a row for the '0000' entry for the corresponding state.
Let me know if you need more information! I can't figure this out.
select x.NAICS, x.StateProvince, x.StateProvinceCode,
emd.FinalDemandOutput,
(x.JobsMaintained * isnull(wd.AvgSalary2017, 0)) * emd.FinalDemandOutput TotalEconomicImpact,
(x.HeadcountExtrapolated * isnull(wd.AvgSalary2017, 0)) * emd.FinalDemandOutput TotalEconomicImpact_HC,
st.MinWage,
x.JobsMaintained * isnull(wd.AvgSalary2017, 0) TotalWages,
x.HeadcountExtrapolated * isnull(wd.AvgSalary2017, 0) TotalWages_HC,
from(
select c.CorporationKey, c.SupplierKey, c.SurveyPeriodKey, sp.year, sp.Quarter, sp.QuarterNum, c.Headcount, c.PYAllocatedRevenue,
c.PYAllocatedJob, c.CYAllocatedRevenue, c.extrapolationfactor, left(concat(ic.Code, '000000'), 6) NAICS, sl.Description StateProvince,
sl.StateCode StateProvinceCode,
(jm.Pct * c.Headcount) as JobsMaintained,
c.CSId_, c.CSSupplierId_, c.ImpactFactor3_Annual, ((c.Headcount/c.extrapolationfactor) * c.ImpactFactor3_Annual) HeadcountExtrapolated
from x
left join WageData wd on Substring(left(concat(x.NAICS, '000000'), 6), 1,4) = substring(wd.NAICS, 1, 4)
left join EconomicMultiplierData4DigitNAICS emd on x.StateProvince = emd.statename
and emd.year = (select max(emd2.year) from EconomicMultiplierData4DigitNAICS emd2 where emd2.statename = x.StateProvince)
and (case when Substring(left(concat(x.NAICS, '000000'), 6), 1,4) = substring(emd.NAICS, 1, 4)
then Substring(left(concat(x.NAICS, '000000'), 6), 1,4)
else '0000'
end) = substring(emd.NAICS, 1, 4)
That is incredibly hard to read, but I think you want something like this:
For the join:
left join EconomicMultiplierData4DigitNAICS emd on x.StateProvince = emd.statename
and emd.year = (select max(emd2.year) from EconomicMultiplierData4DigitNAICS emd2 where emd2.statename = x.StateProvince)
and emd.NAICS = x.NAICS
For the Select:
ISNULL(emd.NAICS,'000000')
Left join will return NULL, then you can use ISNULL to instead select your default value of '000000' in that situation.
EDIT: After comment below, this instead may be closer to the desired result:
For the join:
left join EconomicMultiplierData4DigitNAICS emd on x.StateProvince = emd.statename
and emd.year = (select max(emd2.year) from EconomicMultiplierData4DigitNAICS emd2 where emd2.statename = x.StateProvince)
and emd.NAICS = x.NAICS
left join EconomicMultiplierData4DigitNAICS emdFallback on x.StateProvince = emdFallback.statename
and emdFallback.year = (select max(emd2.year) from EconomicMultiplierData4DigitNAICS emd2 where emd2.statename = x.StateProvince)
and emdFallback.NAICS = '000000'
For the Select:
ISNULL(emd.[FieldName],emdFallback.[FieldName]) [FieldName]
This does make the select a bit more tedious, and may need a DISTINCT.
I imagine there is a better/more clever way to do what you want, though I can't think of it at the moment.

Progress SQL Column cannot be found or is not specified for query

I'm writing SQL against a Progress 10.2B07 database and am getting the following error "Column 'OUTERINVOICEHEADER.MEMBERID' cannot be found or is not specified for query (13865).
Here is the query:
select concat(substring(OuterInvoiceHeader.sold_to_cust_nbr, 1, 6) + '-', OuterInvoiceHeader.sold_to_cust_seq) as MemberID,
sum(OuterInvoiceHeader.net_weight) as TotalInvoicePounds,
sum(OuterInvoiceHeader.net_weight / 2000) as TotalTons,
sum(OuterInvoiceHeader.invoice_amt) as InvoiceAmount,
sum(InvoiceSurcharges.Surcharge) as Surcharges,
sum(OuterInvoiceHeader.invoice_amt - InvoiceSurcharges.Surcharge) as Total,
sum(Returns.qty_received) as PoundsReturned
from AXS.PUB.ivc_header OuterInvoiceHeader
inner join
(select m.invoice_nbr, sum(m.extension) Surcharge from AXS.PUB.ivc_mchgs m
inner join
AXS.PUB.ivc_header h
on h.invoice_nbr = m.invoice_nbr
group by m.invoice_nbr) InvoiceSurcharges
on OuterInvoiceHeader.invoice_nbr = InvoiceSurcharges.invoice_nbr
left outer join
(select concat(substring(ReturnHeader.ship_to_nbr, 1, 6)+'-',InnerInvoiceHeader.sold_to_cust_seq) as ReturnMemberID,
ReturnHeader.invoice_nbr as ReturnInvoiceNum,
qty_received
from AXS.PUB.return_hdr ReturnHeader
inner join
AXS.PUB.ivc_header InnerInvoiceHeader
on ReturnHeader.invoice_nbr = InnerInvoiceHeader.invoice_nbr
inner join AXS.PUB.return_line ReturnLine
on ReturnHeader.claim_nbr = ReturnLine.claim_nbr
where ReturnInvoiceNum = '0001010914'
group by ReturnMemberID, ReturnInvoiceNum, qty_received) Returns
on OuterInvoiceHeader.MemberID = Returns.ReturnMemberID
--on OuterInvoiceHeader.invoice_nbr = Returns.ReturnInvoiceNum
where OuterInvoiceHeader.sold_to_cust_nbr = '000837' and OuterInvoiceHeader.invoice_date between '06/01/2016' and '06/30/2016' and OuterInvoiceHeader.invoice_status = '5804' and OuterInvoiceHeader.invoice_type='5601'
group by MemberID
The problem is in the left join; the commented out on clause "on OuterInvoiceHeader.invoice_nbr = Returns.ReturnInvoiceNum" will work if uncommented. The "on OuterInvoiceHeader.MemberID = Returns.ReturnMemberID" clause gives me the error.
What I don't understand is that both of these reference a column in the top SELECT statement, the only difference is that one is a concatenation and the other is not.
I hope that I just can't see the forest for the trees here and the answer is simple, so if anyone has any suggestions or questions I'm all ears.
try this:
I replaced the references to the alias MemberID to be the actual concatinated columns CONCAT(SUBSTRING(OuterInvoiceHeader.sold_to_cust_nbr, 1, 6)+'-', OuterInvoiceHeader.sold_to_cust_seq)
SELECT CONCAT(SUBSTRING(OuterInvoiceHeader.sold_to_cust_nbr, 1, 6)+'-', OuterInvoiceHeader.sold_to_cust_seq) AS MemberID
, SUM(OuterInvoiceHeader.net_weight) AS TotalInvoicePounds
, SUM(OuterInvoiceHeader.net_weight / 2000) AS TotalTons
, SUM(OuterInvoiceHeader.invoice_amt) AS InvoiceAmount
, SUM(InvoiceSurcharges.Surcharge) AS Surcharges
, SUM(OuterInvoiceHeader.invoice_amt - InvoiceSurcharges.Surcharge) AS Total
, SUM(Returns.qty_received) AS PoundsReturned
FROM AXS.PUB.ivc_header OuterInvoiceHeader
INNER JOIN
(SELECT m.invoice_nbr
, SUM(m.extension) Surcharge
FROM AXS.PUB.ivc_mchgs m
INNER JOIN AXS.PUB.ivc_header h ON h.invoice_nbr = m.invoice_nbr
GROUP BY m.invoice_nbr) InvoiceSurcharges ON OuterInvoiceHeader.invoice_nbr = InvoiceSurcharges.invoice_nbr
LEFT OUTER JOIN
(SELECT CONCAT(SUBSTRING(ReturnHeader.ship_to_nbr, 1, 6)+'-', InnerInvoiceHeader.sold_to_cust_seq) AS ReturnMemberID
, ReturnHeader.invoice_nbr AS ReturnInvoiceNum
, qty_received
FROM AXS.PUB.return_hdr ReturnHeader
INNER JOIN AXS.PUB.ivc_header InnerInvoiceHeader ON ReturnHeader.invoice_nbr = InnerInvoiceHeader.invoice_nbr
INNER JOIN AXS.PUB.return_line ReturnLine ON ReturnHeader.claim_nbr = ReturnLine.claim_nbr
WHERE ReturnInvoiceNum = '0001010914'
GROUP BY ReturnMemberID
, ReturnInvoiceNum
, qty_received) Returns ON CONCAT(SUBSTRING(OuterInvoiceHeader.sold_to_cust_nbr, 1, 6)+'-', OuterInvoiceHeader.sold_to_cust_seq) = Returns.ReturnMemberID
--on OuterInvoiceHeader.invoice_nbr = Returns.ReturnInvoiceNum
WHERE OuterInvoiceHeader.sold_to_cust_nbr = '000837'
AND OuterInvoiceHeader.invoice_date BETWEEN '06/01/2016' AND '06/30/2016'
AND OuterInvoiceHeader.invoice_status = '5804'
AND OuterInvoiceHeader.invoice_type = '5601'
GROUP BY CONCAT(SUBSTRING(OuterInvoiceHeader.sold_to_cust_nbr, 1, 6)+'-', OuterInvoiceHeader.sold_to_cust_seq);
Basically you need to keep in mind the order which SQL statements are executed:
FROM clause
WHERE clause
GROUP BY clause
HAVING clause
SELECT clause
ORDER BY clause
That's a computed column alias and thus the error. You should consider using the entire expression rather like
on concat(substring(OuterInvoiceHeader.sold_to_cust_nbr, 1, 6) + '-', OuterInvoiceHeader.sold_to_cust_seq) = Returns.ReturnMemberID
Instead of on OuterInvoiceHeader.MemberID = Returns.ReturnMemberID. As well, change any other place where you are using the same alias. You can and should use that alias only in a outer query and not in the same query.

select from subquery select where condition throws error

I have the below query where I am selecting from another subquery with where condition
if not exists
(select #DocTaxID from (select bundlechecklist.Bundle_TXN_ID, documentchecklist.Doc_Checklist_TXN_ID, documentchecklist.Doc_Type_Name from ecm.bundle_checklist_txn bundlechecklist
left outer join [ECM].[Document_Checklist_TXN] documentchecklist on documentchecklist.Bundle_TXN_ID = bundlechecklist.Bundle_TXN_ID
where bundlechecklist.originating_tran_id = "AMD"
and bundle_name = 'Line')
where #DocTaxID is not null )
begin
insert into [ECM].[Document_Checklist_TXN]
(bundle_txn_id, document_action_rule_id, action_rule_name, doc_type_name, cp_document_name, document_id, doc_status_code)
values
(1, 17, 'A', 'DEv', 'Dec', 12, 'Pend')
end
DocTaxID is integer field.
And the error I am getting is "Incorrect syntax near the keyword 'where'."
You need a table alias:
select #DocTaxID
from (select bundlechecklist.Bundle_TXN_ID, documentchecklist.Doc_Checklist_TXN_ID, documentchecklist.Doc_Type_Name
from ecm.bundle_checklist_txn bundlechecklist left outer join
[ECM].[Document_Checklist_TXN] documentchecklist
on documentchecklist.Bundle_TXN_ID = bundlechecklist.Bundle_TXN_ID
where bundlechecklist.originating_tran_id = 'AMD' and bundle_name = 'Line'
) d
-------^
where #DocTaxID is not null ;
Somehow, I think there is a much simpler way to express this logic, but off-hand, it is not clear exactly what it is doing.

BigQuery raises exception if query with joins are not flattened

Query is:
select
cb.subnum as subnum,
last(
if(
(if(cu.smartcard_number is not null, 1, 0)) +
(if(rr.smart_card_number is not null, 1, 0)) > 0, 1, 0)
) as econnected_i,
from
combined.table1 as cb
left outer join each dataflow_raw_eu.table2 as cu
on cu.smartcard_number = cb.smart_card_num
left outer join each dataflow_raw_eu.table3 as rr
on rr.smart_card_number = cb.smart_card_num
group by subnum
The error is:
Error: Ambiguous field name 'imported_at' in JOIN. Please use the table qualifier before field name.
I noticed that when it runs with only one join, of either table, then the query succeeds. imported_at is a timestamp field shared by all 3 tables (the only field shared by all 3), but it is not included in the query.
If I select flatten_results in the BigQuery options, then the query succeeds; but I wish to run future queries with nested records. None of the tables in the above query have a repeated or record field.
Looks like this can be GBQ bug
Try below for workaround
SELECT
cb.subnum AS subnum,
LAST(
IF(
(IF(cu.smartcard_number IS NOT NULL, 1, 0)) +
(IF(rr.smart_card_number IS NOT NULL, 1, 0)) > 0, 1, 0)
) AS econnected_i,
FROM
combined.table1 AS cb
LEFT OUTER JOIN EACH (SELECT smartcard_number FROM dataflow_raw_eu.table2) AS cu
ON cu.smartcard_number = cb.smart_card_num
LEFT OUTER JOIN EACH (SELECT smart_card_number FROM dataflow_raw_eu.table3) AS rr
ON rr.smart_card_number = cb.smart_card_num
GROUP BY subnum
Please note, depends on logic and nature of data in dataflow_raw_eu.table2 and dataflow_raw_eu.table3 , you might consider using GROUP BY in subselects, like below
SELECT smartcard_number FROM dataflow_raw_eu.table2 GROUP BY smartcard_number
and
SELECT smart_card_number FROM dataflow_raw_eu.table3 GROUP BY smart_card_number

Sybase Adaptive Server Enterprise - SQL Row Comparison

I'm querying a Sybase Adaptive Server Enterprise (ASE) Database and need to compare rows i.e. row 1 with 2, 2 with 3 etc. I do not want to have to use Cursors for performance reasons. I am thinking that a self join is the answer but the ID's are not sequential i.e. 1, 2, 3, 4 . I have tried creating a column in a temp table using the Row_Number function but it appears that the function is not supported. The below is the query that obtains the requisite data (without the self Join). Does anyone know to compare rows without using cursors in this situation?
SELECT h.HeaderIdS, w.WrapUpIdS, h.CallStarttimeDtTm, h.CallEndtimeDtTm, h.InvestorIdS, h.AdviserIdS, h.BadgeIdS, h.EmployerNoIdS, h.ContactTypeCdS, w.CallTypeCdS, w.SubTypeCdS, w.ProductCdS, h.TeamCodeCdS, h.ContactedByCdS,
h.AgentIdS, h.SystemTypeCdS
INTO #tempHeader
FROM WrapUpHeader h
--Criteria
INNER JOIN WrapUp w ON h.HeaderIdS = w.HeaderIdS And w.StatusCdS = 'Active'
WHERE h.StatusCdS = 'Active'
AND h.CallStartTimeDtTm >= #FromDate
AND h.CallStartTimeDtTm < DateAdd(dd,1,#ToDate)
AND h.TeamCodeCdS = #BusinessUnit
AND ((h.AdviserIdS IS NULL) OR (h.AdviserIdS IS NOT NULL AND h.AdviserIdS <> #AdviserNo))
AND ((h.BadgeIdS IS NULL) OR (h.BadgeIdS IS NOT NULL AND h.BadgeIdS <> #DealerGroup))
AND ((h.EmployerNoIdS IS NULL) OR (h.EmployerNoIdS IS NOT NULL AND h.EmployerNoIdS <> #EmployerNo))
AND ((w.ProductCdS IS NULL) OR (w.ProductCdS IS NOT NULL AND w.ProductCdS <> #Product))
AND ((w.CallTypeCdS IS NULL) OR (w.CallTypeCdS IS NOT NULL AND w.CallTypeCdS <> #CallType))
AND ((w.SubTypeCdS IS NULL) OR (w.SubTypeCdS IS NOT NULL AND w.SubTypeCdS <> #SubType))
SELECT
Distinct RTRIM(th.headerids) as 'CALLIDA',
th.callstarttimedttm as 'TimeA',
RTRIM(th.investorids) as 'AccountIDA',
RTRIM(e.entitynametxm) as 'StaffMemberA',
Count(th.investorids) as 'RepeatCallA'
INTO #TABLEA
from #tempHeader tH
inner join wrapupdetail d on d.wrapupids = th.wrapupids
inner join entity e on e.entityids = th.agentids
left outer join notes note on note.contactids = th.headerids
left outer join ownershiptasks ot on note.OwnershipTasksIds =ot.OwnershipTasksIds
order by th.investorids, th.callstarttimedttm