BigQuery raises exception if query with joins are not flattened - google-bigquery

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

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.

I am converting Oracle queries to Standard Bigquery, i am gettting error "IN subquery is not supported inside join predicate."

I have converted oracle query into below standard bq but in last statement(IN subquery). I am getting error:
"IN subquery is not supported inside join predicate."
Please advise how to use IN subquery in bq in the below code
#Last part of the code
INNER JOIN (
SELECT
DISTINCT `domain-rr.oracle_DB_DB.he_project_assoc`.PARENT_ISBN
PARENT_ISBN,
SUM (`domain-rr.DB_RPT.PROJECT_GR_QTY`.GR_QTY) GR_QTY
FROM
`domain-rr.oracle_DB_DB.he_project_assoc`
INNER JOIN
`domain-rr.DB_RPT.PROJECT_GR_QTY`
ON
`domain-rr.oracle_DB_DB.he_project_assoc`.child_ISBN = `domain-
rr.DB_RPT.PROJECT_GR_QTY`.BIC_GCISBN
AND `domain-rr.oracle_DB_DB.he_project_assoc`.BREAK_LABEL <>
'Associated ISBNs'
GROUP BY
`domain-rr.oracle_DB_DB.he_project_assoc`.PARENT_ISBN) xx
ON
yy.PARENT_ISBN = xx.PARENT_ISBN
AND yy.CIRCULATION_INT < xx.GR_QTY
AND yy.PARENT_ISBN IN
( SELECT
DISTINCT _BIC_GCISBN
FROM
`domain-rr.DB_RPT.BIC_GM_AGCPOAODS00_BO_VW`
INNER JOIN
`domain-rr.oracle_DB_boadmin.fiscal_bo`
ON
_BIC_ZC2GRIRIN = 'G'
AND _BIC_ZCLOEKZ = ' '
AND SUBSTR (BOUND_DATE, 1, 6) = `domain-
rr.oracle_DB_boadmin.fiscal_bo`.PRIOR_FISC_YEAR_MONTH )
Can you try like this:
Select * from (
#Last part of the code
INNER JOIN (
SELECT
DISTINCT `pearson-rr.oracle_grdw_grdw.he_project_assoc`.PARENT_ISBN
PARENT_ISBN,
SUM (`pearson-rr.GRDW_RPT.PROJECT_GR_QTY`.GR_QTY) GR_QTY
FROM
`pearson-rr.oracle_grdw_grdw.he_project_assoc`
INNER JOIN
`pearson-rr.GRDW_RPT.PROJECT_GR_QTY`
ON
`pearson-rr.oracle_grdw_grdw.he_project_assoc`.child_ISBN = `pearson-
rr.GRDW_RPT.PROJECT_GR_QTY`.BIC_GCISBN
AND `pearson-rr.oracle_grdw_grdw.he_project_assoc`.BREAK_LABEL <>
'Associated ISBNs'
GROUP BY
`pearson-rr.oracle_grdw_grdw.he_project_assoc`.PARENT_ISBN) xx
ON
yy.PARENT_ISBN = xx.PARENT_ISBN
AND yy.CIRCULATION_INT < xx.GR_QTY
) AA
where AA.PARENT_ISBN IN
( SELECT
DISTINCT _BIC_GCISBN
FROM
`pearson-rr.GRDW_RPT.BIC_GM_AGCPOAODS00_BO_VW`
INNER JOIN
`pearson-rr.oracle_grdw_boadmin.fiscal_bo`
ON
_BIC_ZC2GRIRIN = 'G'
AND _BIC_ZCLOEKZ = ' '
AND SUBSTR (BOUND_DATE, 1, 6) = `pearson-
rr.oracle_grdw_boadmin.fiscal_bo`.PRIOR_FISC_YEAR_MONTH )

SQL View slow when filtered. Is there a clean way to improve performance?

Let me open with:
SHOWPLAN permission denied in database 'MyDatabase'.
With that out of the way, I'll layout my situation.
So, The database I work with has a view that executes fairly quickly.
SELECT * FROM MyView
returns 32 rows in 1 second and includes a non-indexed column of values (IDs) I need to filter on.
If I filter on these IDs directly in the view:
SELECT * FROM MyView WHERE MyView.SomeId = 18
Things slow immensely and it takes 21 seconds to return the 20 rows with that ID.
As an experiment I pushed the unfiltered results into a temporary table and executed the filtered query on the the temporary table:
IF OBJECT_ID('tempdb..#TEMP_TABLE') IS NOT NULL
BEGIN
DROP TABLE #TEMP_TABLE
END
SELECT * INTO #TEMP_TABLE
FROM MyView;
SELECT *
FROM #TEMP_TABLE
WHERE #TEMP_TABLE.SomeId = 18
DROP TABLE #TEMP_TABLE
And found that it returns the filtered results far faster (roughly 1 second)
Is there a cleaner syntax or pattern that can be implemented to achieve the same performance?
UPDATE: View Definition and Description
Manually obfuscated, but I was careful so hopefully there aren't many errors. Still waiting on SHOWPLAN permissions, so Execution Plan is still pending.
The view's purpose is to provide a count of all the records that belong to a specific component (CMP.COMPONENT_ID = '100') grouped by location.
"Belonging" is determined by the record's PROC_CODE (mapped through PROC_ID) being within the CMP's inclusion range (CMP_INCs) and not in the CMP's exclusion range (CMP_EXCs).
In practice, exclusion ranges are created for individual codes (the bounds are always equal) making it sufficient to check that the code is not equal a bound.
PROC_CODES can (and don't always) have an alphabetic prefix or suffix, which makes the ISNUMERIC() comparison necessary.
Records store PROC_IDs for their PROC_CODEs, so it's necessary to convert the CMP's PROC_CODE ranges into a set of PROC_IDs for identifying which records belong to that component
The performance issue occurs when trying to filter by DEPARTMENT_ID or LOCATION_ID
[CO_RECORDS] is also a view, but if it's that deep I'm going turf this to someone with less red tape to fight through.
CREATE VIEW [ViewsSchema].[MyView] AS
WITH
CMP_INCs AS (SELECT RNG.*, COALESCE(RNG.RANGE_END, RNG.RANGE_BEG) [SAFE_END] FROM DBEngine.DBO.DB_CMP_RANGE [RNG] WHERE [RNG].COMPONENT_ID = '100'),
CMP_EXCs AS (SELECT CER.* FROM DBEngine.DBO.DB_CMP_EXC_RANGE CER WHERE CER.COMPONENT_ID = '100'),
CMP_PROC_IDs AS (
SELECT
DBEngine_ProcTable.PROC_ID [CMP_PROC_ID],
DBEngine_ProcTable.PROC_CODE [CMP_PROC_CODE],
DB_CmpTable.COMPONENT_ID [CMP_ID],
MAX(DB_CmpTable.COMPONENT_NAME) [CMP_NAME]
FROM [DBEngine].DBO.DBEngine_ProcTable DBEngine_ProcTable
LEFT JOIN CMP_INCs ON ISNUMERIC(DBEngine_ProcTable.PROC_CODE) = ISNUMERIC(CMP_INCs.RANGE_BEG)
AND(DBEngine_ProcTable.PROC_CODE = CMP_INCs.RANGE_BEG
OR DBEngine_ProcTable.PROC_CODE BETWEEN CMP_INCs.RANGE_BEG AND CMP_INCs.SAFE_END)
INNER JOIN DBEngine.DBO.DB_CmpTable ON CMP_INCs.COMPONENT_ID = DB_CmpTable.COMPONENT_ID
LEFT JOIN CMP_EXCs EXCS ON EXCS.COMPONENT_ID = DB_CmpTable.COMPONENT_ID AND EXCS.EXCL_RANGE_END = DBEngine_ProcTable.PROC_CODE
WHERE EXCS.EXCL_RANGE_BEG IS NULL
GROUP BY
DBEngine_ProcTable.PROC_ID,
DBEngine_ProcTable.PROC_CODE,
DBEngine_ProcTable.BILL_DESC,
DBEngine_ProcTable.PROC_NAME,
DB_CmpTable.COMPONENT_ID
)
SELECT
RECORD.LOCATION_NAME [LOCATION_NAME]
, RECORD.LOCATION_ID [LOCATION_ID]
, MAX(RECORD.[Department]) [DEPARTMENT]
, RECORD.[Department ID] [DEPARTMENT_ID]
, SUM(RECORD.PROCEDURE_QUANTITY) [PROCEDURE_COUNT]
FROM DBEngineCUSTOMRPT.ViewsSchema.CO_RECORDS [RECORDS]
INNER JOIN CMP_PROC_IDs [CV] ON [CV].CMP_PROC_ID = [RECORDS].PROC_ID
CROSS JOIN (SELECT DATEADD(M, DATEDIFF(M, 0,GETDATE()), 0) [FIRSTOFTHEMONTH]) VARS
WHERE [RECORDS].TYPE = 1
AND ([RECORDS].VOID_DATE IS NULL OR [RECORDS].VOID_DATE >= VARS.[FIRSTOFTHEMONTH] )
AND [RECORDS].POST_DATE < VARS.[FIRSTOFTHEMONTH]
AND [RECORDS].DOS_MONTHS_BACK = 2
GROUP BY [RECORDS].LOCATION_NAME, [RECORDS].[Department ID]
GO
Based on the swift down votes, the answer to my question is
'No, there is not a clean syntax based solution for the improved
performance, and asking for one is ignorant of the declarative nature
of SQL you simple dirty plebeian'.
From the requests for the view's definition, it's clear that performance issues in simple queries should be addressed by fixing the structure of the objects being queried ('MyView' in this case) rather than syntactical gymnastics.
For interested parties the issue was resolved by adding a Row_Number() column to the final select in the view definition, wrapping it in a CTE, and using the new column in an always true filter while selecting the original columns.
I have no idea if this is the optimal solution. It doesn't feel good to me, but it appears to be working.
CREATE VIEW [ViewsSchema].[MyView] AS
WITH
CMP_INCs AS (SELECT RNG.*, COALESCE(RNG.RANGE_END, RNG.RANGE_BEG) [SAFE_END] FROM DBEngine.DBO.DB_CMP_RANGE [RNG] WHERE [RNG].COMPONENT_ID = '100'),
CMP_EXCs AS (SELECT CER.* FROM DBEngine.DBO.DB_CMP_EXC_RANGE CER WHERE CER.COMPONENT_ID = '100'),
CMP_PROC_IDs AS (
SELECT
DBEngine_ProcTable.PROC_ID [CMP_PROC_ID],
DBEngine_ProcTable.PROC_CODE [CMP_PROC_CODE],
DB_CmpTable.COMPONENT_ID [CMP_ID],
MAX(DB_CmpTable.COMPONENT_NAME) [CMP_NAME]
FROM [DBEngine].DBO.DBEngine_ProcTable DBEngine_ProcTable
LEFT JOIN CMP_INCs ON ISNUMERIC(DBEngine_ProcTable.PROC_CODE) = ISNUMERIC(CMP_INCs.RANGE_BEG)
AND(DBEngine_ProcTable.PROC_CODE = CMP_INCs.RANGE_BEG
OR DBEngine_ProcTable.PROC_CODE BETWEEN CMP_INCs.RANGE_BEG AND CMP_INCs.SAFE_END)
INNER JOIN DBEngine.DBO.DB_CmpTable ON CMP_INCs.COMPONENT_ID = DB_CmpTable.COMPONENT_ID
LEFT JOIN CMP_EXCs EXCS ON EXCS.COMPONENT_ID = DB_CmpTable.COMPONENT_ID AND EXCS.EXCL_RANGE_END = DBEngine_ProcTable.PROC_CODE
WHERE EXCS.EXCL_RANGE_BEG IS NULL
GROUP BY
DBEngine_ProcTable.PROC_ID,
DBEngine_ProcTable.PROC_CODE,
DBEngine_ProcTable.BILL_DESC,
DBEngine_ProcTable.PROC_NAME,
DB_CmpTable.COMPONENT_ID
),
RESULTS as (
SELECT
RECORD.LOCATION_NAME [LOCATION_NAME]
, RECORD.LOCATION_ID [LOCATION_ID]
, MAX(RECORD.[Department]) [DEPARTMENT]
, RECORD.[Department ID] [DEPARTMENT_ID]
, SUM(RECORD.PROCEDURE_QUANTITY) [PROCEDURE_COUNT]
, ROW_NUMBER() OVER (ORDER BY TDL.[Medical Department ID], TDL.[BILL_AREA_ID], TDL.JP_POS_NAME) [ROW]
FROM DBEngineCUSTOMRPT.ViewsSchema.CO_RECORDS [RECORDS]
INNER JOIN CMP_PROC_IDs [CV] ON [CV].CMP_PROC_ID = [RECORDS].PROC_ID
CROSS JOIN (SELECT DATEADD(M, DATEDIFF(M, 0,GETDATE()), 0) [FIRSTOFTHEMONTH]) VARS
WHERE [RECORDS].TYPE = 1
AND ([RECORDS].VOID_DATE IS NULL OR [RECORDS].VOID_DATE >= VARS.[FIRSTOFTHEMONTH] )
AND [RECORDS].POST_DATE < VARS.[FIRSTOFTHEMONTH]
AND [RECORDS].DOS_MONTHS_BACK = 2
GROUP BY [RECORDS].LOCATION_NAME, [RECORDS].[Department ID]
)
SELECT
[LOCATION_NAME]
, [LOCATION_ID]
, [DEPARTMENT]
, [DEPARTMENT_ID]
, [PROCEDURE_COUNT]
FROM RESULTS
WHERE [ROW] > 0
GO

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.

SQL JOIN with a condition

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.