I am trying to join three tables in Snowflake, but getting an error on a third one, and not sure if I used a good key :
select
a.CALENDAR_DATE
, a.SALES_DOCUMENT
, a.DOCUMENT_NUMBER_CROSS_BORDER
, *bAUBEL
, *b.NETWR_ship*
, a.Delivery_time
, a.Route_label
, ue.order_ID
from DWHM_MALLGROUP.DM_LOG.SHIPMENTS a
left join (
select
AUBEL,
sum(NETWR) as NETWR_ship
from DWHM_MALLGROUP.SRC_SAP_ERP."2LIS_13_VDITM"
where MATNR in ('10027', '10200', '10402', '10500', '10602', '10603', '10650', '10700')
group by AUBEL
) b
on a.DOCUMENT_NUMBER_CROSS_BORDER = b.AUBEL
where
a.CALENDAR_DATE >= '2020-04-01'
and a.ROUTE in ('CZSK12', 'CZSK21', 'CZSK22', 'CZSK23', 'CZSK24', 'CZSK25', 'CZSK26', 'CZSK27', 'CZSK28', 'CZSK29', 'CZSK30', 'CZSK32', 'CZSK33', 'CZSK34', 'CZSK51', 'CZSK53', 'CZSK54', 'CZSK56')
group by a.CALENDAR_DATE, a.SALES_DOCUMENT, a.DOCUMENT_NUMBER_CROSS_BORDER, b.AUBEL, b.NETWR_ship, a.delivery_time, a.Route_LABEL
left join "DWHM_MALLGROUP"."DM_COMMERCIAL"."UNIT_ECONOMICS" as ue
ON a.SALES_DOCUMENT = ue.order_id
where ue.country = 'SI' and ue.delivery_date >= '2019-08-01'
Your 2nd LEFT JOIN should be moved up to before the WHERE clause:
select
a.CALENDAR_DATE
, a.SALES_DOCUMENT
, a.DOCUMENT_NUMBER_CROSS_BORDER
, b.AUBEL
, b.NETWR_ship
, a.Delivery_time
, a.Route_label
, ue.order_ID
from DWHM_MALLGROUP.DM_LOG.SHIPMENTS a
left join (
select
AUBEL,
sum(NETWR) as NETWR_ship
from DWHM_MALLGROUP.SRC_SAP_ERP."2LIS_13_VDITM"
where MATNR in ('10027', '10200', '10402', '10500', '10602', '10603', '10650', '10700')
group by AUBEL
) b
on a.DOCUMENT_NUMBER_CROSS_BORDER = b.AUBEL
left join "DWHM_MALLGROUP"."DM_COMMERCIAL"."UNIT_ECONOMICS" as ue
ON a.SALES_DOCUMENT = ue.order_id
where
a.CALENDAR_DATE >= '2020-04-01'
and a.ROUTE in ('CZSK12', 'CZSK21', 'CZSK22', 'CZSK23', 'CZSK24', 'CZSK25', 'CZSK26', 'CZSK27', 'CZSK28', 'CZSK29', 'CZSK30', 'CZSK32', 'CZSK33', 'CZSK34', 'CZSK51', 'CZSK53', 'CZSK54', 'CZSK56')
and ue.country = 'SI' and ue.delivery_date >= '2019-08-01'
group by a.CALENDAR_DATE, a.SALES_DOCUMENT, a.DOCUMENT_NUMBER_CROSS_BORDER, b.AUBEL, b.NETWR_ship, a.delivery_time, a.Route_LABEL
NOTE: I am not familiar with the *b that you have in the SELECT clause... it looks like another typo to me, so I removed it.
If you are trying to perform the aggregate (GROUP BY) before the 2nd LEFT JOIN, then you can use a CTE:
WITH CTE_1 AS (
select
a.CALENDAR_DATE
, a.SALES_DOCUMENT
, a.DOCUMENT_NUMBER_CROSS_BORDER
, b.AUBEL
, b.NETWR_ship
, a.Delivery_time
, a.Route_label
from DWHM_MALLGROUP.DM_LOG.SHIPMENTS a
left join (
select
AUBEL,
sum(NETWR) as NETWR_ship
from DWHM_MALLGROUP.SRC_SAP_ERP."2LIS_13_VDITM"
where MATNR in ('10027', '10200', '10402', '10500', '10602', '10603', '10650', '10700')
group by AUBEL
) b
on a.DOCUMENT_NUMBER_CROSS_BORDER = b.AUBEL
where
a.CALENDAR_DATE >= '2020-04-01'
and a.ROUTE in ('CZSK12', 'CZSK21', 'CZSK22', 'CZSK23', 'CZSK24', 'CZSK25', 'CZSK26', 'CZSK27', 'CZSK28', 'CZSK29', 'CZSK30', 'CZSK32', 'CZSK33', 'CZSK34', 'CZSK51', 'CZSK53', 'CZSK54', 'CZSK56')
group by a.CALENDAR_DATE, a.SALES_DOCUMENT, a.DOCUMENT_NUMBER_CROSS_BORDER, b.AUBEL, b.NETWR_ship, a.delivery_time, a.Route_LABEL
) c1
select
c1.CALENDAR_DATE
, c1.SALES_DOCUMENT
, c1.DOCUMENT_NUMBER_CROSS_BORDER
, c1.AUBEL
, c1.NETWR_ship
, c1.Delivery_time
, c1.Route_label
, ue.order_ID
left join "DWHM_MALLGROUP"."DM_COMMERCIAL"."UNIT_ECONOMICS" as ue
ON c1.SALES_DOCUMENT = ue.order_id
and ue.country = 'SI' and ue.delivery_date >= '2019-08-01'
This can (and should, IMO) be cleaned up some more, but I am trying to address the question you asked about joining 3 tables.
There are multiple issues with the SQL.
, *bAUBEL
, *b.NETWR_ship*
we only use * for selecting all fields from a table. For example select A.* , B.col1 from Table_a A , Table_B
sequence for join is
SELECT
FROM Table
JOIN other Table
JOIN Condition
WHERE
GROUP BY
HAVING
Try this SQL
SELECT
a.calendar_date,
a.sales_document,
a.document_number_cross_border,
b.aubel,
b.netwr_ship,
a.delivery_time,
a.route_label,
ue.order_id
FROM
dwhm_mallgroup.dm_log.SHIPMENTS a
left join (
select
AUBEL,
sum(NETWR) as NETWR_ship
from DWHM_MALLGROUP.SRC_SAP_ERP."2LIS_13_VDITM"
where MATNR in ('10027', '10200', '10402', '10500', '10602', '10603', '10650', '10700')
group by AUBEL
) b
on a.DOCUMENT_NUMBER_CROSS_BORDER = b.AUBEL
left join "DWHM_MALLGROUP"."DM_COMMERCIAL"."UNIT_ECONOMICS" as ue ON a.sales_document = ue.order_id
WHERE
a.calendar_date >= '2020-04-01'
AND a.route IN (
'CZSK12',
'CZSK21',
'CZSK22',
'CZSK23',
'CZSK24',
'CZSK25',
'CZSK26',
'CZSK27',
'CZSK28',
'CZSK29',
'CZSK30',
'CZSK32',
'CZSK33',
'CZSK34',
'CZSK51',
'CZSK53',
'CZSK54',
'CZSK56'
)
AND ue.country = 'SI'
AND ue.delivery_date >= '2019-08-01'
GROUP BY
a.calendar_date,
a.sales_document,
a.document_number_cross_border,
b.aubel,
b.netwr_ship,
a.delivery_time,
a.route_label
ue.order_id
I have the following CTE inside a view and I would like to add some NULLIF (or equivalent) function so that If WTHD_BOX16 is NULL then replace with an empty string (blank), otherwise display the value.
WITH VWDETAIL AS
( SELECT VENDOR_ID , 'PA/13679089' AS WTHD_BOX17 , WTHD_BASIS_AMT AS WTHD_BOX18 , YEAR(PYMNT_DT) AS YEAR ,
CASE WHEN PYMNT_DT <= '01/31/2014' THEN '1099' ELSE 'NGC' END AS WTHD_CNTL_ID
FROM PS_WTHD_TRXN_TBL A
WHERE WTHD_CLASS IN ('01','02','07')
AND BUSINESS_UNIT IN ('10000','50000')
AND PYMNT_DT <= CASE BUSINESS_UNIT WHEN '10000' THEN '01/31/2014' ELSE '12/31/2018' END)
, BOX16DATA AS
( SELECT --A.BUSINESS_UNIT, A.VOUCHER_ID,
A.PYMNT_TYPE, SUM(A.PAID_AMT) AS BOX16PAIDAMT, SUM(A.PYMNT_GROSS_AMT) AS WTHD_BOX16, B.VENDOR_ID, YEAR(A.SCHEDULED_PAY_DT) AS 'Year'
FROM PS_PYMNT_VCHR_XREF A
INNER JOIN PS_VOUCHER B ON B.BUSINESS_UNIT = A.BUSINESS_UNIT AND B.VOUCHER_ID = A.VOUCHER_ID
WHERE PYMNT_TYPE = 'W'
AND REMIT_VENDOR = '47860A'
GROUP BY B.VENDOR_ID, A.PYMNT_TYPE, YEAR(A.SCHEDULED_PAY_DT)
)
SELECT A.VENDOR_ID, B.WTHD_BOX16, WTHD_BOX17 , SUM(WTHD_BOX18) AS WTHD_BOX18 , YEAR , WTHD_CNTL_ID
FROM VWDETAIL A
LEFT OUTER JOIN BOX16DATA B ON B.VENDOR_ID = A.VENDOR_ID AND B.Year = YEAR
GROUP BY A.VENDOR_ID , WTHD_BOX17 , YEAR , WTHD_CNTL_ID, B.WTHD_BOX16
ORDER BY A.YEAR
GO
I added the NULLIF to the final Select statement, however I am getting back the error 'Error converting data type varchar to numeric'.
SELECT A.VENDOR_ID, NULLIF(B.WTHD_BOX16, ''), WTHD_BOX17 , SUM(WTHD_BOX18) AS WTHD_BOX18 , YEAR , WTHD_CNTL_ID
FROM VWDETAIL A
LEFT OUTER JOIN BOX16DATA B ON B.VENDOR_ID = A.VENDOR_ID AND B.Year = YEAR
GROUP BY A.VENDOR_ID , WTHD_BOX17 , YEAR , WTHD_CNTL_ID, B.WTHD_BOX16
ORDER BY A.YEAR
GO
How can I fix this so that I will have the numeric values if there isn't a NULL and an empty string for a NULL row? Using MS SQL Server.
you can cast the columns to varchar e.g. cast(col as varchar(50)). blank cannot be converted to numeric.
I have this SQL in SQL Server:
SELECT
Itens.Mercadoria, Mercadoria.Nome, Cabecalho.Data,
SUM(ValorUnitario) AS Total,
SUM(Quantidade) AS Quantidade
FROM
Itens
INNER JOIN
Mercadoria ON Itens.Mercadoria = Mercadoria.Codigo
INNER JOIN
Cabecalho ON Cabecalho.Codigo = Itens.Cabecalho
WHERE
Cabecalho.Data >= '2016-01-01'
AND Cabecalho.Data <= '2018-12-31'
GROUP BY
Itens.Mercadoria, Mercadoria.Nome, Cabecalho.Data
ORDER BY
4 DESC
It is returning the following result.
The highlighted values are repeating, I do not want to be repeated, I want to show only once each item and that the Quantidade and Total fields are SUM.
For example:
`Camisa Polo` -> **Quantidade = 23**
`Calça Jeans` -> **Quantidade = 15**
`Camiseta Estampada` -> **Quantidade = 21**
Assuming thate the relation between Sales and SaleItems is based on SalesId
you can use between assign to your_start_date and your_end_date a proper value
select Products.ProductName
, sum(SaleItems.Price)
, sum(SaleItems.Quantity)
from Products
inner join SaleItems on SaleItems.IdProduct = Products.IdProduct
inner join Sales on Sales.IdSale = SaleItems.IdSale
where SaleDate between your_start_date and your_end_date
group by Products.ProductName
In you case remove or aggregated the Cabecalho.Data column eg:
SELECT Itens.Mercadoria
, Mercadoria.Nome
, SUM(ValorUnitario) AS Total
, SUM(Quantidade) AS Quantidade
FROM Itens INNER JOIN Mercadoria ON Itens.Mercadoria = Mercadoria.Codigo
INNER JOIN Cabecalho ON Cabecalho.Codigo = Itens.Cabecalho
WHERE Cabecalho.Data between '2016-01-01' AND '2018-12-31'
GROUP BY Itens.Mercadoria, Mercadoria.Nome
ORDER BY 4 DESC
or
SELECT Itens.Mercadoria
, Mercadoria.Nome
, max(Cabecalho.Data)
, SUM(ValorUnitario) AS Total
, SUM(Quantidade) AS Quantidade
FROM Itens INNER JOIN Mercadoria ON Itens.Mercadoria = Mercadoria.Codigo
INNER JOIN Cabecalho ON Cabecalho.Codigo = Itens.Cabecalho
WHERE Cabecalho.Data between '2016-01-01' AND '2018-12-31'
GROUP BY Itens.Mercadoria, Mercadoria.Nome
ORDER BY 4 DESC
I have the following queries:
select AccountId
into #liveCustomers
from AccountExtensionBase where New_duos_group not in ('T053','T054')
and New_AccountStage = 7
select AccountId
into #customerWhoLeft
from New_marketmessagein as a
inner join AccountExtensionBase as b on a.new_accountmminid = b.AccountId
where New_MessageTypeCode = '105L'
and a.New_EffectiveFromDate > '30 jun 2016'
and b.New_duos_group not in ('T053','T054')
select
accountid
, New_MPRNNumber
, New_duos_group
, New_CommercialAgreementDayRate
, New_CommercialAgreementNightRate
, New_CommercialAgreementHeatRate
, New_Tariffpriceagreedatsignup
, New_Tariffname
into
#monthCustomers
from
AccountExtensionBase
where
AccountId in (select * from #customerWhoLeft)
or
AccountId in (select * from #liveCustomers)
I now wish to join a table called usagefactorExtensionBase and join only the row containing the most recent read date but when I try to join this to my table of 4985 monthly customers I get like 106,813 rows using this code so I think my join or methodology has gone awry, can someone please help me correct the error so I display the list of monthCustomers plus the read details of their most recent read.
Attempting:
select
accountid
, New_MPRNNumber
, New_duos_group
, New_CommercialAgreementDayRate
, New_CommercialAgreementNightRate
, New_CommercialAgreementHeatRate
, New_Tariffpriceagreedatsignup
, New_Tariffname
, max(b.New_EffectiveFromDate)
, b.New_ActualUsageFactor
, b.New_EstimatedUseage
from
#monthCustomers as a
left join
New_marketmessageinusagefactorExtensionBase as b
on a.AccountId = b.new_accountmmusagefactorid
group by
accountid
, New_MPRNNumber
, New_duos_group
, New_CommercialAgreementDayRate
, New_CommercialAgreementNightRate
, New_CommercialAgreementHeatRate
, New_Tariffpriceagreedatsignup
, New_Tariffname
, b.New_ActualUsageFactor
, b.New_EstimatedUseage
try this,
SELECT
accountid,
New_MPRNNumber,
New_duos_group,
New_CommercialAgreementDayRate,
New_CommercialAgreementNightRate,
New_CommercialAgreementHeatRate,
New_Tariffpriceagreedatsignup,
New_Tariffname,
b.New_EffectiveFromDate,
b.New_ActualUsageFactor,
b.New_EstimatedUseage
FROM #monthCustomers AS a
-- Get only max date rows for each AccountID
LEFT JOIN( SELECT t1.*
FROM New_marketmessageinusagefactorExtensionBase AS t1
INNER JOIN ( SELECT new_accountmmusagefactorid, MAX(New_EffectiveFromDate) AS New_EffectiveFromDate_Max
FROM New_marketmessageinusagefactorExtensionBase
GROUP BY new_accountmmusagefactorid
) AS t2 ON t2.new_accountmmusagefactorid = t1.new_accountmmusagefactorid
AND t2.New_EffectiveFromDate_Max = t1.New_EffectiveFromDate
)AS b
ON a.AccountId = b.new_accountmmusagefactorid
there might be rows with same date, try below if is works,
SELECT
accountid,
New_MPRNNumber,
New_duos_group,
New_CommercialAgreementDayRate,
New_CommercialAgreementNightRate,
New_CommercialAgreementHeatRate,
New_Tariffpriceagreedatsignup,
New_Tariffname,
b.New_EffectiveFromDate,
b.New_ActualUsageFactor,
b.New_EstimatedUseage
FROM #monthCustomers AS a
-- Get only max date rows for each AccountID
LEFT JOIN( SELECT New_MPRNNumber,
New_duos_group,
New_CommercialAgreementDayRate,
New_CommercialAgreementNightRate,
New_CommercialAgreementHeatRate,
New_Tariffpriceagreedatsignup,
New_Tariffname,
MAX(New_EffectiveFromDate) AS New_EffectiveFromDate,
New_ActualUsageFactor,
New_EstimatedUseage
FROM New_marketmessageinusagefactorExtensionBase AS t1
GROUP BY
New_MPRNNumber,
New_duos_group,
New_CommercialAgreementDayRate,
New_CommercialAgreementNightRate,
New_CommercialAgreementHeatRate,
New_Tariffpriceagreedatsignup,
New_Tariffname,
New_ActualUsageFactor,
New_EstimatedUseage
)AS b
ON a.AccountId = b.new_accountmmusagefactorid
The following CASE statement is returning 2 rows, 1 with the joindate = to the join date (cd.user_d1) if the person is a member and null if there is no join date on the record. How can i get the CASE statement to only return 1 row with the joindate field either null or with the member's join date?
I've searched and found solutions for other type fields with SUM, but nothing for date fields. Any help would be greatly appreciated.
SELECT DISTINCT
c.master_customer_id ,
c.SUB_CUSTOMER_ID ,
c.PRIMARY_EMAIL_ADDRESS ,
c.FIRST_NAME ,
c.INFORMAL_SALUTATION ,
c.LAST_NAME ,
c.LABEL_NAME ,
c.PRIMARY_JOB_TITLE ,
cad.company_name ,
ca.ADDRESS_1 ,
ca.ADDRESS_2 ,
ca.ADDRESS_3 ,
ca.ADDRESS_4 ,
ca.CITY ,
ca.STATE ,
ca.POSTAL_CODE ,
ca.COUNTRY_DESCR ,
c.PRIMARY_URL ,
c.BIRTH_DATE ,
CASE WHEN cd.DEMOGRAPHIC_SUBCODE = 'join_date'
AND cd.user_d1 IS NOT NULL THEN cd.USER_D1
ELSE NULL
END AS JOINDATE ,
CASE WHEN cc.comm_type_code = 'EMAIL'
AND cc.primary_flag <> 'Y' THEN cc.formatted_phone_address
END AS secondary_email
FROM customer c
LEFT OUTER JOIN CUS_DEMOGRAPHIC cd ON cd.MASTER_CUSTOMER_ID = c.MASTER_CUSTOMER_ID
LEFT OUTER JOIN CUS_ADDRESS ca ON ca.MASTER_CUSTOMER_ID = c.MASTER_CUSTOMER_ID
LEFT OUTER JOIN CUS_ADDRESS_DETAIL cad ON cad.CUS_ADDRESS_ID = ca.CUS_ADDRESS_ID
LEFT OUTER JOIN CUS_COMMUNICATION cc ON cc.MASTER_CUSTOMER_ID = c.MASTER_CUSTOMER_ID
WHERE c.CUSTOMER_STATUS_CODE = 'active'
AND c.ALLOW_EMAIL_FLAG = 'Y'
AND cad.PRIORITY_SEQ = 0
AND c.PRIMARY_EMAIL_ADDRESS <> ' '
ORDER BY c.MASTER_CUSTOMER_ID