How/where do I use PIVOT? - sql

I have a table of data that shows multiple rows for a single piece of data. In the example below, I have a column called, "Location Type" that shows, "BH" and "TPI". BH and TPI each have a specific location shown in the "Location" column. Instead of having a new row for BH and TPI, I'd like two new columns that show the location data for that row. I included a couple of rows of data below. I suspect I need to use PIVOT here but I've been having a hard time figuring out where the PIVOT needs to come in. Could anybody provide some guidance or show me a solution?
Here's a sample of the data from the query.
API14
First Prod Date
Location Type
Location
43013540070000
2/8/2021
BH
Township 3S Range 4W Section 17 DUCHESNE County
43013540070000
2/8/2021
TPI
Township 3S Range 4W Section 18 DUCHESNE County
Here's the format I would like to see:
API14
First Prod Date
BH Location
TPI Location
43013540070000
2/8/2021
Township 3S Range 4W Section 17 DUCHESNE County
Township 3S Range 4W Section 18 DUCHESNE County
Here's my code so far:
DECLARE #SearchYear AS VARCHAR(4) = '2021'
DECLARE #SearchMonth AS VARCHAR(2) = '6'
SELECT
dbo.BuildAPI14(Well.WellID, Construct.SideTrack, Construct.Completion) AS 'API14',
CAST(ConstructDate.EventDate AS DATE) AS 'First Prod Date',
Loc.LocType AS 'Location Type',
CONCAT('Township ',LocExt.Township,LocExt.TownshipDir,' ','Range ',LocExt.Range,LocExt.RangeDir,' Section ',LocExt.Sec,' ',RefCounty.CountyName,' County') AS 'Location',
tblAPDTracker.SpacingRule AS 'Spacing Rule',
Lease.Number AS 'Entity Number',
WellHistory.WHComments AS 'Well History Comments'
FROM Well
LEFT JOIN Construct ON Construct.WellKey = Well.PKey
LEFT JOIN ConstructReservoir ON ConstructReservoir.ConstructKey = Construct.PKey
LEFT JOIN Lease ON Lease.Pkey = ConstructReservoir.LeaseKey
LEFT JOIN WellHistory ON WellHistory.WellKey = Construct.WellKey
LEFT JOIN tblAPDTracker ON LEFT(tblAPDTracker.APINO,10) = Well.WellID
LEFT JOIN Loc ON loc.ConstructKey = Construct.PKey AND Loc.LocType IN ('BH','TPI')
LEFT JOIN LocExt ON LocExt.LocKey = Loc.PKey
LEFT JOIN ConstructDate ON ConstructDate.ConstructKey = Construct.PKey AND ConstructDate.Event = 'FirstProduction'
LEFT JOIN RefCounty ON RefCounty.PKey = LocExt.County
WHERE
WorkType = 'ENTITY' AND
WellHistory.ModifyUser = 'UTAH\rachelmedina' AND
YEAR(WellHistory.ModifyDate) = #SearchYear AND
MONTH(WellHistory.ModifyDate) = #SearchMonth
GROUP BY
Well.WellID,
Construct.SideTrack,
Construct.Completion,
ConstructDate.EventDate,
Loc.LocType,
LocExt.Township,
LocExt.TownshipDir,
LocExt.Range,
LocExt.RangeDir,
LocExt.Sec,
RefCounty.CountyName,
tblAPDTracker.SpacingRule,
Lease.Number,
WellHistory.WHComments,
WellHistory.ModifyDate
ORDER BY
Well.WellId,
WellHistory.ModifyDate DESC

Select *
from
(
SELECT
dbo.BuildAPI14(Well.WellID, Construct.SideTrack, Construct.Completion) AS 'API14',
CAST(ConstructDate.EventDate AS DATE) AS 'First Prod Date',
Loc.LocType AS 'Location Type',
CONCAT('Township ',LocExt.Township,LocExt.TownshipDir,' ','Range ',LocExt.Range,LocExt.RangeDir,' Section ',LocExt.Sec,' ',RefCounty.CountyName,' County') AS 'Location' --,
-- tblAPDTracker.SpacingRule AS 'Spacing Rule',
-- Lease.Number AS 'Entity Number',
-- WellHistory.WHComments AS 'Well History Comments'
FROM Well
LEFT JOIN Construct ON Construct.WellKey = Well.PKey
LEFT JOIN ConstructReservoir ON ConstructReservoir.ConstructKey = Construct.PKey
LEFT JOIN Lease ON Lease.Pkey = ConstructReservoir.LeaseKey
LEFT JOIN WellHistory ON WellHistory.WellKey = Construct.WellKey
LEFT JOIN tblAPDTracker ON LEFT(tblAPDTracker.APINO,10) = Well.WellID
LEFT JOIN Loc ON loc.ConstructKey = Construct.PKey AND Loc.LocType IN ('BH','TPI')
LEFT JOIN LocExt ON LocExt.LocKey = Loc.PKey
LEFT JOIN ConstructDate ON ConstructDate.ConstructKey = Construct.PKey AND ConstructDate.Event = 'FirstProduction'
LEFT JOIN RefCounty ON RefCounty.PKey = LocExt.County
WHERE
WorkType = 'ENTITY' AND
WellHistory.ModifyUser = 'UTAH\rachelmedina' AND
YEAR(WellHistory.ModifyDate) = #SearchYear AND
MONTH(WellHistory.ModifyDate) = #SearchMonth
GROUP BY
Well.WellID,
Construct.SideTrack,
Construct.Completion,
ConstructDate.EventDate,
Loc.LocType,
LocExt.Township,
LocExt.TownshipDir,
LocExt.Range,
LocExt.RangeDir,
LocExt.Sec,
RefCounty.CountyName,
tblAPDTracker.SpacingRule,
Lease.Number,
WellHistory.WHComments,
WellHistory.ModifyDate
) p
pivot (min(p.Location) for [Location Type] in ([TPI], [BH])) pvt
The values in the pivoted column need an aggregation operator (sum, avg, min, max etc) so pick one like min or max which won't try to do anything with a string, but which will do something if you have multiple occurrences in the pivoting column (Location here).
I've also commented out the columns selected which don't appear in your sample results, which may affect what needs to appear in the GROUP BY clause.

Another alternative from pivot is to just re-join the tables using different aliases to differentiate from the "BH" vs "TPI" instances. I also simplified the longer table names with short aliases "w" for Well, "wh" for wellhouse, etc.
Also, by seeing the hierarchy on how A -> B -> C -> D tables helps identify where the related components are. Then I copied those out for the location downward.
I removed the location type as a column and group by since the query joins simultaneously to the BH and TPI respectively.
DECLARE #SearchYear AS VARCHAR(4) = '2021'
DECLARE #SearchMonth AS VARCHAR(2) = '6'
SELECT
dbo.BuildAPI14(w.WellID, c.SideTrack, c.Completion) API14,
CAST(cd.EventDate AS DATE) 'First Prod Date',
CONCAT('Township ', LocExtBH.Township, LocExtBH.TownshipDir,
' ','Range ', LocExtBH.Range, LocExtBH.RangeDir,
' Section ', LocExtBH.Sec,
' ', rcBH.CountyName, ' County') 'BH Location',
CONCAT('Township ', LocExtTPI.Township, LocExtTPI.TownshipDir,
' ','Range ', LocExtTPI.Range, LocExtTPI.RangeDir,
' Section ', LocExtTPI.Sec,
' ', rcTPI.CountyName, ' County') 'TPI Location',
ADP.SpacingRule 'Spacing Rule',
l.Number 'Entity Number',
wh.WHComments 'Well History Comments'
FROM
Well w
LEFT JOIN tblAPDTracker ADP
ON w.WellID = LEFT(trk.APINO,10)
LEFT JOIN Construct c
ON w.PKey = c.WellKey
LEFT JOIN ConstructReservoir cr
ON c.PKey = cr.ConstructKey
LEFT JOIN Lease l
ON cr.LeaseKey = l.Pkey
LEFT JOIN WellHistory wh
ON c.WellKey = wh.WellKey
LEFT JOIN ConstructDate cd
ON c.PKey = cd.ConstructKey
AND cd.Event = 'FirstProduction'
LEFT JOIN Loc LocBH
ON c.PKey = locBH.ConstructKey
AND LocBH.LocType = 'BH'
LEFT JOIN LocExt LocExtBH
ON LocBH.PKey = LocExtBH.LocKey
LEFT JOIN RefCounty rcBH
ON LocExtBH.County = rcBH.PKey
LEFT JOIN Loc LocTPI
ON c.PKey = LocTPI.ConstructKey
AND LocTPI.LocType = 'TPI'
LEFT JOIN LocExt LocExtTPI
ON LocTPI.PKey = LocExtTPI.LocKey
LEFT JOIN RefCounty rcTPI
ON LocExtTPI.County = rcTPI.PKey
WHERE
w.WorkType = 'ENTITY'
AND wh.ModifyUser = 'UTAH\rachelmedina'
AND YEAR(wh.ModifyDate) = #SearchYear
AND MONTH(wh.ModifyDate) = #SearchMonth
GROUP BY
w.WellID,
c.SideTrack,
c.Completion,
cd.EventDate,
LocExtBH.Township,
LocExtBH.TownshipDir,
LocExtBH.Range,
LocExtBH.RangeDir,
LocExtBH.Sec,
rcBH.CountyName,
ADP.SpacingRule,
l.Number,
wh.WHComments,
wh.ModifyDate
ORDER BY
w.WellId,
wh.ModifyDate DESC

Related

Rownumber is not working as expected in report builder?

So I have a report that used this prod from sql like so:
alter PROCEDURE [dbo].[PHA00B01801_VN_BCThuocdakedontheoyeucau]
--declare
#TUNGAY DATETIME = '20220202',
#DENNGAY DATETIME = '20220204',
#KHODUOC_ID int = null,
#TENBACSI nvarchar(max) = null,
#MABENHVIEN VARCHAR(10)
AS
set #TENBACSI = ISNULL(#TENBACSI, '')
select st.TENBACSI, st.SOTOATHUOC, st.TENTHUOC, st.SOLUONG as SOLUONGTHUOC, st.KHOXUAT, st.GHICHU from
(
select nv.TENNHANVIEN as TENBACSI, ntkb.SOTHUTUTOA as SOTOATHUOC, d.TENDUOCDAYDU as TENTHUOC, nttt.SOLUONG as SOLUONG, ntkb.KHOXUAT_ID as KHOXUAT, nttt.GHICHU as GHICHU from TT_NGOAITRU_KHAMBENH_TOATHUOC as ntkb
inner join TT_NGOAITRU_TOATHUOC as nttt on nttt.KHAMBENH_TOATHUOC_ID = ntkb.KHAMBENH_TOATHUOC_ID
inner join TM_NHANVIEN as nv on nv.NHANVIEN_ID = ntkb.BACSI_ID
inner join TT_DUOC_CHUNGTU as ct on ntkb.CHUNGTUPHATTHUOC_ID = ct.CHUNGTU_ID
inner join TT_DUOC_CHUNGTU_CHITIET as ctct on ctct.CHUNGTU_ID = ct.CHUNGTU_ID
left join TM_DUOC as D on d.DUOC_ID = ctct.DUOC_ID
where ntkb.KHOXUAT_ID = #KHODUOC_ID or #KHODUOC_ID is null and CONVERT(DATE, CT.NGAYCHUNGTU) BETWEEN CONVERT(DATE,#TUNGAY) AND CONVERT(DATE,#DENNGAY)
group by nv.TENNHANVIEN, ntkb.SOTHUTUTOA, d.TENDUOCDAYDU, nttt.SOLUONG, ntkb.KHOXUAT_ID , nttt.GHICHU
union all
select nv.TENNHANVIEN as TENBACSI, NTT.SOTHUTUTOA as SOTOATHUOC, d.TENDUOCDAYDU as TENTHUOC, ntt.SOLUONG as SOLUONG, NKB.KHODUOC_ID as KHOXUAT, NTT.GHICHU as GHICHU from TT_NOITRU_KHAMBENH as NKB
inner join TT_NOITRU_TOATHUOC as NTT on NKB.KHAMBENH_ID = NTT.KHAMBENH_ID
inner join TM_NHANVIEN as nv on nv.NHANVIEN_ID = NKB.BACSIKHAM_ID
inner join TT_DUOC_CHUNGTU as ct on NTT.CHUNGTU_ID = ct.CHUNGTU_ID
inner join TT_DUOC_CHUNGTU_CHITIET as ctct on ctct.CHUNGTU_ID = ct.CHUNGTU_ID
left join TM_DUOC as D on d.DUOC_ID = ctct.DUOC_ID
where NKB.KHODUOC_ID = #KHODUOC_ID or #KHODUOC_ID is null and CONVERT(DATE, CT.NGAYCHUNGTU) BETWEEN CONVERT(DATE,#TUNGAY) AND CONVERT(DATE,#DENNGAY)
group by nv.TENNHANVIEN, NTT.SOTHUTUTOA, d.TENDUOCDAYDU, ntt.SOLUONG, NKB.KHODUOC_ID, NTT.GHICHU
) st where st.TENBACSI like '%' + #TENBACSI + '%'
group by st.TENBACSI, st.SOTOATHUOC, st.TENTHUOC, st.SOLUONG, st.KHOXUAT, st.GHICHU
order by st.TENBACSI
From that i used report builder to build a report where I group the TENBACSI aka doctors name and the SOTHUTUTOA aka the case id :
[1]: https://i.stack.imgur.com/NucZh.png
but when I tried to created row number for the 1st by using:
=RowNumber("TENBACSI")
It return wield Num Id such:
[2]: https://i.stack.imgur.com/HhDww.png
Then I tried to used:
=RunningValue(Fields!TENBACSI.Value,Count,"GROUP1")
Then I the result of all 1 in row number id.
I tried to look for answer but there is not much help

Remove row from SQL pivot when fields null

The following query below listed generates blank values in a row.
-- Simplify the pivot selection query by separating the query using a with clause
WITH pivot_data AS(
SELECT va.identity,
vc.units,
s.field_name "Sample ID",
s.id_text "Lab ID",
TO_CHAR(str.result_value, S_FORMATMASK_PACKAGE.s_FormatMask(vc.analysis, s.id_numeric))result_value
FROM sample s
LEFT OUTER JOIN client c ON c.id = s.client_id
LEFT OUTER JOIN samp_test_result str ON (s.id_numeric = str.id_numeric
AND s.id_text = str.id_text and str.result_value is not null)
LEFT OUTER JOIN versioned_analysis va ON (va.identity = str.analysis)
LEFT OUTER JOIN versioned_component vc ON (vc.analysis = va.identity
AND vc.analysis_version = va.analysis_version
AND vc.name = str.component_name)
WHERE s.fas_sample_type = sample_pkg.get_leaf_sample
AND s.status = sample_pkg.get_authorised_sample
AND s.flg_released = constant_pkg.get_true
AND vc.flg_report = constant_pkg.get_true
AND c.id = UPPER ('I000009')
AND s.ID_NUMERIC between TO_NUMBER(2126) and TO_NUMBER(12917) and str.result_value <> 0
)
SELECT pvt1.*
FROM(SELECT * FROM pivot_data PIVOT (MAX(result_value) result_value, MAX(units) units FOR identity IN('NIR_N' "Nitrogen",
'XRF_P' "Phosphorus",
'XRF_K' "Potassium",
'XRF_CA' "Calcium",
'XRF_MG' "Magnesium",
'XRF_S' "Sulphur",
'XRF_SI' "Silicon",
'XRF_ZN' "Zinc",
'XRF_MN' "Manganese",
'XRF_CU' "Copper",
'XRF_FE' "Iron"))) pvt1
How do I remove a row that contains null fields

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 Server 2012 : Multiple Queries in One Stored Procedure

How do I create Stored Procedure on these queries and he output should show which check the anomaly was captured from, along with all the relevant data.
SELECT cm.Cust_id, cm.cust_ref_id4, cm.cust_ref_id3, cm.plan_group, cm.Company_name, cm.Cust_firstname, cm.Cust_lastname
COALESCE(c.pkCustomerID, c2.fkCustomerID, c3.pkCustomerID, c4.pkCustomerID) AS pkCustomerID, c3.CompanyName FROM PRODUCTIONSQL.[SigmaPaTri].[dbo].[CUSTOMER_MASTER] cm
LEFT JOIN PHOENIX.CORE.dbo.Customers AS c ON cust_ref_id4 = c.pkCustomerID AND cm.cust_ref_id3 = c.pkCustomerID AND cm.cust_ref_id3 >= 1000000 AND cm.Cust_firstname + ' ' + cm.Cust_lastname = c.CompanyName
LEFT JOIN PHOENIX.CORE.dbo.Contracts AS c2 ON cm.cust_ref_id3 = c2.ConfirmationNumber
WHERE cm.cust_status IN ('A','P','R','G') AND COALESCE(c.pkCustomerID, c2.fkCustomerID) IS NULL ORDER BY cust_ref_id4;
and
SELECT [pkCustomerID],b.[pkContractID],[pkCustomerTypeID],[CustomerType],b.[ContractType] AS Contractype1,c.[ContractType]
AS Contractype2 FROM [CORE].[dbo].[Customers] a
JOIN [CORE].[dbo].[CustomerTypes] ON [pkCustomerTypeID] = [fkCustomerTypeID]
LEFT JOIN (SELECT [pkContractID],[ContractType],[fkCustomerID] FROM [CORE].[dbo].[Contracts]
JOIN [CORE].[dbo].[ContractTypes] ON [fkContractTypeID] = [pkContractTypeID] WHERE [ContractType] NOT LIKE 'Holdover%')b ON a.pkCustomerID=b.fkCustomerID
LEFT JOIN (SELECT [pkContractID],[fkCustomerID],[ContractType] FROM [CORE].[dbo].[Contracts]
JOIN [CORE].[dbo].[ContractTypes] ON [fkContractTypeID] = [pkContractTypeID] WHERE ContractType LIKE 'Holdover%')c ON b.fkCustomerID=c.fkCustomerID WHERE [CustomerType] IN ('Customer','Former Customer') AND (b.ContractType IS NULL OR c.ContractType IS NULL)
You question is lacking a very important piece of information, the explanation of what you are trying to do. I took a shot in the dark here as a guess to what you might be looking for. BTW, I ran this through a formatter so it was legible.
SELECT 'Found in query1'
,cm.Cust_id
,cm.cust_ref_id4
,cm.cust_ref_id3
,cm.plan_group
,cm.Company_name
,cm.Cust_firstname
,cm.Cust_lastname
,COALESCE(c.pkCustomerID, c2.fkCustomerID, c3.pkCustomerID, c4.pkCustomerID) AS pkCustomerID
,c3.CompanyName
FROM PRODUCTIONSQL.[SigmaPaTri].[dbo].[CUSTOMER_MASTER] cm
LEFT JOIN PHOENIX.CORE.dbo.Customers AS c ON cust_ref_id4 = c.pkCustomerID
AND cm.cust_ref_id3 = c.pkCustomerID
AND cm.cust_ref_id3 >= 1000000
AND cm.Cust_firstname + ' ' + cm.Cust_lastname = c.CompanyName
LEFT JOIN PHOENIX.CORE.dbo.Contracts AS c2 ON cm.cust_ref_id3 = c2.ConfirmationNumber
WHERE cm.cust_status IN (
'A'
,'P'
,'R'
,'G'
)
AND COALESCE(c.pkCustomerID, c2.fkCustomerID) IS NULL
SELECT 'Found in query 2'
,[pkCustomerID]
,b.[pkContractID]
,[pkCustomerTypeID]
,[CustomerType]
,b.[ContractType] AS Contractype1
,c.[ContractType] AS Contractype2
FROM [CORE].[dbo].[Customers] a
INNER JOIN [CORE].[dbo].[CustomerTypes] ON [pkCustomerTypeID] = [fkCustomerTypeID]
LEFT JOIN (
SELECT [pkContractID]
,[ContractType]
,[fkCustomerID]
FROM [CORE].[dbo].[Contracts]
INNER JOIN [CORE].[dbo].[ContractTypes] ON [fkContractTypeID] = [pkContractTypeID]
WHERE [ContractType] NOT LIKE 'Holdover%'
) b ON a.pkCustomerID = b.fkCustomerID
LEFT JOIN (
SELECT [pkContractID]
,[fkCustomerID]
,[ContractType]
FROM [CORE].[dbo].[Contracts]
INNER JOIN [CORE].[dbo].[ContractTypes] ON [fkContractTypeID] = [pkContractTypeID]
WHERE ContractType LIKE 'Holdover%'
) c ON b.fkCustomerID = c.fkCustomerID
WHERE [CustomerType] IN (
'Customer'
,'Former Customer'
)
AND (
b.ContractType IS NULL
OR c.ContractType IS NULL
)

How to select a single row where multiple rows exist from a table

I have two tables th_Therapy_Note and th_Approved. When a note in th_Therapy_Note gets approved, the application inserts a record to th_Approved.
A note can get rejected for several reasons after it has been approved (don't ask me why, as I did not design this app, lol). So if a note is rejected after being approved, another entry to th_Approved is inserted.
th_Approved.th_approved_isApproved is a boolean (bit) column, so depending on the status, the note entry in this table for this column in true or false
So multiple lines for the same note can exist in th_Approved with different th_Approved.th_approved_isApproved status, the last entry being the most recent one and correct status
The main purpose for the below query is to select notes that are ready to be 'finalized'. The issue with the below query is in the last inner join filter 'AND th_Approved.th_approved_isApproved = 1' This is selecting notes that effectively have been approved, meaning they should have an entry in th_Approved and th_Approved.th_approved_isApproved is true.
This works perfect for notes with single entries in th_Approved, but notes with multiple entries in th_Approved (as explained above) represent an issue if the last entry for that particular note is false. The query will still pick it up because there is at least one entry with th_Approved.th_approved_isApproved as true, even when last correct status is false. I need to only look at this last entry to be able to determine the correct status for a note and select it or not depending on the status.
Last part of the query (and th_Therapy_Note.th_note_id=16239) is just for my testing as this note has multiple entries, but the final will not have this.
How can I solve my issue? I have been looking at several strategies with no luck.....Hopefully I made sense :) thanks
SELECT Distinct Convert(varchar,th_Therapy_Note.th_note_id) as NOTEID, '054' as PROGCODE, Rtrim(ch.child_caseNumber) as CASEID,
Case th_TherapyType.shortname when 'ST' then 'SP' else rtrim(th_TherapyType.shortname) end as SERVTYPE, Convert(varchar,th_Therapy_Note.th_note_dateofservice,101) as DELSERVDATE,
Cast(((Select sum(th_TherapyServiceProvided.units) From th_TherapyServiceProvided where th_DirectServices.th_ds_id = th_TherapyServiceProvided.th_ds_id)/60) as varchar) as SERVHRS,
Cast(((Select sum(th_TherapyServiceProvided.units) From th_TherapyServiceProvided where th_DirectServices.th_ds_id = th_TherapyServiceProvided.th_ds_id)%60) as varchar) as SERVMIN,
'1' as METHOD, isnull(th_Users.trad_id, ' ') as SPROVNUM, th_Users.th_user_lname, '' as COVISIT
FROM th_Therapy_Note INNER JOIN
child_tbl AS ch ON th_Therapy_Note.child_id = ch.child_recordId INNER JOIN
th_DirectServices ON th_Therapy_Note.th_note_id = th_DirectServices.th_note_id INNER JOIN
LookUp_contactType ON th_Therapy_Note.contact_type_id = LookUp_contactType.recId INNER JOIN
th_Users ON th_Therapy_Note.service_coordinator = th_Users.th_user_email INNER JOIN
th_TherapyType ON th_Therapy_Note.therapy_type = th_TherapyType.id INNER JOIN
th_Approved ON th_Therapy_Note.th_note_id = th_Approved.th_note_id AND th_Approved.th_approved_isApproved = 1
WHERE (ch.child_recordId =
(SELECT MAX(child_recordId) AS Expr1
FROM child_tbl
WHERE (child_caseNumber = ch.child_caseNumber)))
and th_Therapy_Note.th_note_dateofservice > '4/22/2014' and th_Therapy_Note.th_note_id=16239
You can use a "MAX" trick (or "MIN" or similar). On a date or unique column is typical.
Here is a generic Northwind example that uses the MAX(OrderDate) (where a customer has more than one order).
The logic below falls apart if there are 2 orders with the same order-date, and those dates are the "max" date. So a unique identifier that is orderable is preferred)
Use Northwind
GO
Select cust.* , ords.*
from dbo.Customers cust
LEFT OUTER JOIN dbo.Orders ords
ON
(
ords.CustomerID = cust.CustomerID
AND ords.OrderDate =
(SELECT MAX(OrderDate)
FROM dbo.Orders innerords
WHERE innerords.CustomerID = cust.CustomerID
)
)
where cust.CustomerID = 'ALFKI'
Since you have a sequential ID on th_Approved, then I'd use that. Integer comparison on id is perfect. Date/Datetime comparison can sometimes add problems.
So I'd try this:
SELECT Distinct
Convert(varchar,th_Therapy_Note.th_note_id) as NOTEID,
'054' as PROGCODE,
Rtrim(ch.child_caseNumber) as CASEID,
Case th_TherapyType.shortname
when 'ST' then 'SP'
else rtrim(th_TherapyType.shortname)
end as SERVTYPE,
Convert(varchar,th_Therapy_Note.th_note_dateofservice,101) as DELSERVDATE,
Cast(((
Select sum(th_TherapyServiceProvided.units)
From th_TherapyServiceProvided
where th_DirectServices.th_ds_id = th_TherapyServiceProvided.th_ds_id)/60) as varchar
) as SERVHRS,
Cast(((
Select sum(th_TherapyServiceProvided.units)
From th_TherapyServiceProvided
where th_DirectServices.th_ds_id = th_TherapyServiceProvided.th_ds_id)%60) as varchar
) as SERVMIN,
'1' as METHOD,
isnull(th_Users.trad_id, ' ') as SPROVNUM,
th_Users.th_user_lname, '' as COVISIT
FROM th_Therapy_Note
INNER JOIN child_tbl AS ch ON th_Therapy_Note.child_id = ch.child_recordId
INNER JOIN th_DirectServices ON th_Therapy_Note.th_note_id = th_DirectServices.th_note_id INNER JOIN LookUp_contactType ON th_Therapy_Note.contact_type_id = LookUp_contactType.recId INNER JOIN th_Users ON th_Therapy_Note.service_coordinator = th_Users.th_user_email
INNER JOIN th_TherapyType ON th_Therapy_Note.therapy_type = th_TherapyType.id
INNER JOIN th_Approved ON th_Approved.th_approved_id=(
SELECT MAX(th_approved_id)
FROM th_Approved
WHERE th_Therapy_Note.th_note_id = th_Approved.th_note_id)
WHERE ch.child_recordId = (
SELECT MAX(child_recordId)
FROM child_tbl
WHERE child_caseNumber = ch.child_caseNumber)
AND th_Therapy_Note.th_note_dateofservice > '4/22/2014'
AND th_Approved.th_approved_isApproved = 1
AND th_Therapy_Note.th_note_id=16239
Without access to your dataset to test this with this is the best I can give you.
In essence what I am doing is filtering out the duplicates using a CTE and the TSQL command ROW NUMBER using whatever date function you have. then placing the filtered out list into your main query.
;with fixDuplicateCTE(
SELECT m.th_note_id, m.tag
FROM ( SELECT TH_NOTE_ID ROW_NUMBER OVER(partition by th_note_id ORDER BY [SOME DATE FUNCTION YOU HAVE!!!!!] desc) as tag FROM th_approved) as m
INNER JOIN th_approved AS a on m.th_note_id = a.th_note_id
WHERE m.tag = 1
)
SELECT Distinct Convert(varchar,th_Therapy_Note.th_note_id) as NOTEID, '054' as PROGCODE, Rtrim(ch.child_caseNumber) as CASEID,
Case th_TherapyType.shortname
when 'ST' then 'SP' else rtrim(th_TherapyType.shortname) end as SERVTYPE, Convert(varchar,th_Therapy_Note.th_note_dateofservice,101) as DELSERVDATE,
Cast(((Select sum(th_TherapyServiceProvided.units) From th_TherapyServiceProvided where th_DirectServices.th_ds_id = th_TherapyServiceProvided.th_ds_id)/60) as varchar) as SERVHRS,
Cast(((Select sum(th_TherapyServiceProvided.units) From th_TherapyServiceProvided where th_DirectServices.th_ds_id = th_TherapyServiceProvided.th_ds_id)%60) as varchar) as SERVMIN,
'1' as METHOD, isnull(th_Users.trad_id, ' ') as SPROVNUM, th_Users.th_user_lname, '' as COVISIT
FROM th_Therapy_Note
INNER JOIN child_tbl AS ch ON th_Therapy_Note.child_id = ch.child_recordId
INNER JOIN th_DirectServices ON th_Therapy_Note.th_note_id = th_DirectServices.th_note_id
INNER JOIN LookUp_contactType ON th_Therapy_Note.contact_type_id = LookUp_contactType.recId
INNER JOIN th_Users ON th_Therapy_Note.service_coordinator = th_Users.th_user_email
INNER JOIN th_TherapyType ON th_Therapy_Note.therapy_type = th_TherapyType.id
INNER JOIN fixDuplicateCTE ON th_Therapy_Note.th_note_id = th_Approved.th_note_id AND th_Approved.th_approved_isApproved = 1
WHERE (ch.child_recordId =
(SELECT MAX(child_recordId) AS Expr1
FROM child_tbl
WHERE (child_caseNumber = ch.child_caseNumber)))
and th_Therapy_Note.th_note_dateofservice > '4/22/2014' and th_Therapy_Note.th_note_id=16239