Combine SELECT statements. Help Needed - sql

I have the following two T-SQL statements that I really need to combine:
SELECT Aircraft.Id AS AircraftID, AircraftManufacturers.Name, AircraftModels.ModelName,
Aircraft.ModelSuffix, Aircraft.ImageFileName, Aircraft.Year, Aircraft.SerialNo,
Locations.DescriptionForSite, Aircraft.Description, Aircraft.Description2,
Aircraft.InfoWebAddress, Aircraft.ImageDescription, Advertisers.Id AS AdvertisersID,
Advertisers.Name AS AdvertisersName, Aircraft.AircraftDataId, Aircraft.ForSale, Aircraft.ForLease,
Aircraft.TTAF, Aircraft.ReSend, Aircraft.ReSendReason, Aircraft.Registration, Aircraft.AdType,
Aircraft.HasAlternateImage, Aircraft.AlternateImageDescription,
Aircraft.Price, AircraftModels.AircraftType, Advertisers.CurrentEMagLink, Aircraft.CurrentEMagLink,
Aircraft.Email, Aircraft.IsSold, Aircraft.SoldDate, Aircraft.DateAdded, Aircraft.ExtendedDetails,
Aircraft.LastUpdateDate, Aircraft.ImageCount, Aircraft.ContactTelephone, AircraftModels.id, Advertisers.IsPremiumAdvertiser,
Aircraft.Location, Advertisers.ContactTelephone As AdvertisersTelephone, Aircraft.LastUpdateDate, Aircraft.EndDate, Aircraft.VideoLink
FROM (((Aircraft
INNER JOIN Advertisers ON Aircraft.AdvertiserId = Advertisers.Id)
INNER JOIN AircraftModels ON Aircraft.AircraftModelId = AircraftModels.Id)
INNER JOIN AircraftManufacturers ON AircraftModels.ManufacturerId = AircraftManufacturers.Id)
INNER JOIN Locations ON Aircraft.LocationId = Locations.Id
JOIN iter$simple_intlist_to_tbl(#ids) i ON AircraftModels.id = i.number
WHERE (Aircraft.IsActive=1 AND Advertisers.IsActive=1 AND (Aircraft.EndDate>=#Date OR Aircraft.EndDate Is Null) AND Locations.DescriptionForSite LIKE #Location)
OR (Advertisers.IsActive=1 AND Aircraft.IsSold=1 AND Aircraft.SoldDate>=#Date2 AND Locations.DescriptionForSite LIKE #Location)
ORDER BY Advertisers.IsPremiumAdvertiser ASC, Aircraft.DateAdded DESC, Aircraft.ListPosition DESC,
Aircraft.LastUpdateDate, AircraftManufacturers.Name, AircraftModels.ModelName, Aircraft.ModelSuffix,
Aircraft.Id DESC
and
SELECT TOP (1) dbo.Addresses.Email, dbo.Addresses.Contact, dbo.Addresses.Telephone1
FROM dbo.AdvertiserAddressLink
INNER JOIN dbo.Addresses ON dbo.AdvertiserAddressLink.AddressId = dbo.Addresses.Id
WHERE (dbo.AdvertiserAddressLink.AdvertiserId = 'AdvertisersID') <--see above
AND (dbo.Addresses.AddressType = 1 OR dbo.Addresses.AddressType = 0)
ORDER BY dbo.Addresses.AddressType DESC, dbo.Addresses.Sequence

It looks like you want to do TOP 1 in the second query based on a correlated parameter from the first?
You can use APPLY for this.
A simple example.
SELECT t.name, ca.name
FROM sys.tables t
CROSS APPLY (SELECT TOP 1 *
FROM sys.columns c
WHERE c.object_id=t.object_id
ORDER BY name) ca

Related

SQL Server aggregate function without group by

I want to include tcon.Inductive_Injection_Hours, tcon.Capacitive_Injection_Hours without applying group by. How can I do that?
SELECT
bp.Serial_Number,
tcon.Serial_Number AS ConverterSerialNumber,
MAX(tcon.Time_Stamp) AS DateStamp,
tcon.Inductive_Injection_Hours,
tcon.Capacitive_Injection_Hours
FROM
dbo.Bypass AS bp
INNER JOIN
dbo.Converter AS c ON bp.Bypass_ID = c.Bypass_ID
INNER JOIN
dbo.Converter_Tel_Data AS tcon ON c.Converter_ID = tcon.Converter_ID
WHERE
(bp.Site_ID = 7)
GROUP BY
bp.Serial_Number, tcon.Serial_Number,
tcon.Inductive_Injection_Hours, tcon.Capacitive_Injection_Hours
ORDER BY
ConverterSerialNumber
I have figured it out.
select [data].Serial_Number,Time_Stamp,Inductive_Injection_Hours,Capacitive_Injection_Hours,b.Serial_Number from Converter_Tel_Data as [data]
inner join dbo.Converter AS c On [data].Converter_ID = c.Converter_ID
inner join dbo.Bypass as b on c.Bypass_ID = b.Bypass_ID
WHERE
(Time_Stamp = (SELECT MAX(Time_Stamp) FROM Converter_Tel_Data WHERE Converter_ID = [data].Converter_ID)) And ([data].Site_ID=7)
ORDER BY [data].Serial_Number
You can use row_number - either in a CTE/derived table or using a trick with TOP 1.
Select Top 1 With Ties
bp.Serial_Number
, tcon.Serial_Number AS ConverterSerialNumber
, tcon.Time_Stamp AS DateStamp
, tcon.Inductive_Injection_Hours
, tcon.Capacitive_Injection_Hours
From dbo.Bypass AS bp
Inner Join dbo.Converter AS c On bp.Bypass_ID = c.Bypass_ID
Inner Join dbo.Converter_Tel_Data AS tcon ON c.Converter_ID = tcon.Converter_ID
Where bp.Site_ID = 7
Order By
row_number() over(Partition By bp.Serial_Number Order By tcon.Time_Stamp desc)
This should return the latest row from the tconn table for each bp.Serial_Number.

Removing duplicates rows in left Joining query

SELECT Rec.[Reg_ID]
,Rec.[Reg_No]
,Rec.[Case_ID]
,Det.Deleted AS CaseDeleted
,[Status].[Status]
,Det.[Unit_Submission_Date] AS [Signature]
,TD.TargetDate AS [Target]
,TD.TargetID
FROM [dbo].[Regestrations] Rec
LEFT JOIN [dbo].[Reg_Details] Det ON Rec.Case_ID = Det.CaseID
LEFT JOIN [dbo].[lkpStatus] [Status] ON Rec.Status_ID = [Status].StatusID
LEFT JOIN TargetDate TD ON TD.RecommId = Rec.Reg_ID
WHERE (Det.MissionID = 50 AND [Status].[Status] = 1 AND Rec.Deleted = 0 AND Det.Deleted = 0)
GROUP BY Rec.[Reg_ID],Rec.[Reg_No],Rec.[Case_ID]
,[Status].[Status]
,Det.[Unit_Submission_Date]
,TD.TargetDate
,Det.Deleted
,TD.TargetID
ORDER BY TD.TargetID desc
I have the above query that is supposed to return rows with unique Rec.[Reg_No]. But joined table TargetDate can have duplicate Rec.[Reg_ID] and if thats the case i get duplicate Rec.[Reg_No] rows in my results.
Table TargetDate has a date time column so i want to eliminate the duplicate Rec.[Reg_No] by selecting 1 row with the latest date value from table TargetDate.
How do modify my Join condition or the query where clause to achive the above?
One way is to use a window function such as ROW_NUMBER() that will generate sequential number based on the specified partition. This generated number can then be used to get the latest row.
SELECT Reg_ID, Reg_No, Case_ID, CaseDeleted, [Status], Signature, [Target], TargetID
FROM
(
SELECT Rec.[Reg_ID]
,Rec.[Reg_No]
,Rec.[Case_ID]
,Det.Deleted AS CaseDeleted
,[Status].[Status]
,Det.[Unit_Submission_Date] AS [Signature]
,TD.TargetDate AS [Target]
,TD.TargetID
,RN = ROW_NUMBER() OVER (PARTITION BY Rec.[Reg_No] ORDER BY TD.TargetID DESC)
FROM [BOI].[dbo].[Regestrations] Rec
LEFT JOIN [dbo].[Reg_Details] Det ON Rec.Case_ID = Det.CaseID
LEFT JOIN [dbo].[lkpStatus] [Status] ON Rec.Status_ID = [Status].StatusID
LEFT JOIN TargetDate TD ON TD.RecommId = Rec.Reg_ID
WHERE (Det.MissionID = 50 AND [Status].[Status] = 1 AND Rec.Deleted = 0 AND Det.Deleted = 0)
) subQuery
WHERE RN = 1
ORDER BY TargetID desc
This query can work correctly if you remove TD.TargetDate from GROUP BY clause and compute what you really need in output - MAX(TD.TargetDate)
But preferable way it to avoid GROUP BY clause at all:
...
FROM [BOI].[dbo].[Regestrations] Rec
LEFT JOIN [dbo].[Reg_Details] Det ON Rec.Case_ID = Det.CaseID
LEFT JOIN [dbo].[lkpStatus] [Status] ON Rec.Status_ID = [Status].StatusID
OUTER APPLY(
SELECT TOP 1 td.TargetDate, td.TargetID
FROM TargetDate TD
WHERE TD.RecommId = Rec.Reg_ID
ORDER BY TD.TargetDate DESC
) td
...
You should first find latest TargetDate for each Reg_ID or RecommId. Then you can use your normal join with TargetDate table just this time with matching both the RecommId and TargetDate.
Try this Query:
SELECT Rec.[Reg_ID]
,Rec.[Reg_No]
,Rec.[Case_ID]
,Det.Deleted AS CaseDeleted
,[Status].[Status]
,Det.[Unit_Submission_Date] AS [Signature]
,TD.TargetDate AS [Target]
,TD.TargetID
FROM [BOI].[dbo].[Regestrations] Rec
LEFT JOIN [dbo].[Reg_Details] Det ON Rec.Case_ID = Det.CaseID
LEFT JOIN [dbo].[lkpStatus] [Status] ON Rec.Status_ID = [Status].StatusID
LEFT JOIN (SELECT RecommId, MAX(TargetDate) MaxTargetDate GROUP BY RecommId) TDWithLatestDate ON TDWithLatestDate.RecommId = Rec.Reg_ID
LEFT OUTER JOIN TargetDate ON TD.RecommId = TDWithLatestDate.RecommId AND TD.TargetDate = TDWithLatestDate.MaxTargetDate
WHERE (Det.MissionID = 50
AND [Status].[Status] = 1
AND Rec.Deleted = 0
AND Det.Deleted = 0
)
GROUP BY Rec.[Reg_ID]
,Rec.[Reg_No]
,Rec.[Case_ID]
,[Status].[Status]
,Det.[Unit_Submission_Date]
,TD.TargetDate
,Det.Deleted
,TD.TargetID
ORDER BY TD.TargetID desc
You can improve this query if you want to avoid tie when there more than one record fighting to be latest.

SQL Random Item for each USER

I have been searching and cannot find the right way to do this. In my query below, What I need is one random C.CREDENTIALING_K for each U.USER_K. I know the newid() will be needed somewhere, I just cannot find the proper place to put it.
select
U.USER_K,
U.FULLNAME as 'Chg_By',
CONVERT(DATE,AL.AUDITDATETIME) as 'Verif_Date',
P.ID,
P.LONGNAME,
CONVERT(DATE,P.DATEOFBIRTH) as 'DOB',
C.entity_k,
R.DESCRIPTION as 'CVI_TYPE',
C.CREDENTIALING_K,
CG.GROUPDESCRIPTION,
C.APPLICATION_RECEIVED,
R1.DESCRIPTION as 'Cur_STATUS',
CONVERT(DATE,C.USERDEF_D3) as 'MSO_DUE_DT'
from
VisualCACTUS.AUDITLOG AL
JOIN VisualCACTUS.USERS U
on U.user_k = AL.USER_K
join VisualCACTUS.CREDENTIALING C
JOIN VisualCACTUS.PROVIDERS P
on P.provider_k = C.PROVIDER_K
JOIN visualcactus.CREDENTIALINGGROUP CG
on CG.CREDENTIALINGGROUP_K = C.CREDENTIALINGGROUP_K
JOIN VisualCACTUS.REFTABLE R
on R.reftable_k = CG.TYPE_RTK
JOIN VisualCACTUS.REFTABLE R1
ON R1.REFTABLE_K = C.CREDENTIALINGSTATUS_RTK
--JOIN VisualCACTUS.CREDENTIALINGASSIGNMENTS CA
--on CA.credentialing_k = CA.credentialing_k
on C.CREDENTIALING_K = AL.FILE_PRIMARYKEY
where
AUDITLOG_K in (select AUDITLOG_K from VisualCACTUS.AUDITLOG_RECORDLEVEL where TABLE_NAME = 'CREDENTIALING '
and
AUDITLOG_RECORDLEVEL_K in (SELECT AUDITLOG_RECORDLEVEL_K from VisualCACTUS.AUDITLOG_FIELDLEVEL where NEWVALUE_SHORT = 'D2680X38F3'))
and
C.USERDEF_L1 = 0
and
CG.TYPE_RTK NOT IN ('D2870MPPSO','D2LC0YR0AR','D2DD1EIY5X')
and
CG.TYPE_RTK NOT LIKE ('SSP%')
and
C.credentialing_k not in (select credentialing_k from VisualCACTUS.CREDENTIALINGASSIGNMENTS where EA_K in (select ea_k from visualcactus.entityassignments where entity_k in ('HCA0000039',
'HCA0000040',
'HCA0000041',
'HCA0000043',
'HCA0000096',
'HCA0000095',
'HCA0000337',
'HCA0000903',
'HCA0000904',
'HCA0000905',
'HCA0000906',
'HCA0000080')))
and
CONVERT(DATE, AUDITDATETIME) = DATEADD(day, -1, convert(date, GETDATE()))
order by 'Chg_By'
Make a correlated subquery to return random CREDENTIALING_K
CREDENTIALING_K=(select top 1 C1.CREDENTIALING_K
from VisualCACTUS.CREDENTIALING c1
Where P.provider_k = C1.PROVIDER_K
order by newid())
Note : If needed add the filter that you have used for VisualCACTUS.CREDENTIALING table inside subquery too

returning only the most recent record in dataset

I have a query returning data for several dates.
I want to return only record with the most recent date in the field SAPOD (the date is in fact CYYMMDD where C=0 before 2000 and 1 after 2000 and I can show this as YYYYMMDD using SAPOD=Case when LEFT(SAPOD,1)=1 then '20' else '19' end + SUBSTRING(cast(sapod as nvarchar(7)),2,7))
here is my query:
SELECT GFCUS, Ne.NEEAN, SCDLE, SAPOD, SATCD,CUS.GFCUN, BGCFN1,
BGCFN2, BGCFN3, SV.SVCSA, SV.SVNA1, SV.SVNA2, SV.SVNA3,
SV.SVNA4, SV.SVNA5, SV.SVPZIP, SV.NONUK
FROM SCPF ACC
INNER JOIN GFPF CUS ON GFCPNC = SCAN
LEFT OUTER JOIN SXPF SEQ ON SXCUS = GFCUS AND SXPRIM = ''
LEFT OUTER JOIN SVPFClean SV ON SVSEQ = SXSEQ
LEFT OUTER JOIN BGPF ON BGCUS = GFCUS AND BGCLC = GFCLC
LEFT OUTER JOIN NEPF NE ON SCAB=NE.NEAB and SCAN=ne.NEAN and SCAS=ne.NEAS
LEFT OUTER JOIN SAPF SA ON SCAB=SAAB and SCAN=SAAN and SCAS=SAAS
WHERE
(SATCD>500 and
scsac='IV' and
scbal = 0 and
scai30<>'Y' and
scai14<>'Y' and
not exists(select * from v5pf where v5and=scan and v5bal<>0))
GROUP BY GFCUS, Ne.NEEAN, SCDLE, SAPOD, SATCD,
CUS.GFCUN, BGCFN1, BGCFN2, BGCFN3, SV.SVCSA,
SV.SVNA1, SV.SVNA2, SV.SVNA3, SV.SVNA4, SV.SVNA5, SV.SVPZIP, SV.NONUK
ORDER BY MAX(SCAN) ASC, SAPOD DESC
I am getting results like the below where there are several transactions by a customer, and we only want to show the data of the most recent transaction:
So how can I show just the most recent transaction? Is this a case where I should use an OUTER APPLY or CROSS APPY?
EDIT:
Sorry I should clarify that I need the most recent date for each of the unique records in the field NEEAN which is the Account number
You can use ROW_NUMBER() as follows:
SELECT
ROW_NUMBER() OVER (PARTITION BY Ne.NEEAN ORDER BY SAPOD DESC) AS [Row],
GFCUS, Ne.NEEAN, SCDLE, SAPOD, SATCD,CUS.GFCUN, BGCFN1,
BGCFN2, BGCFN3, SV.SVCSA, SV.SVNA1, SV.SVNA2, SV.SVNA3,
SV.SVNA4, SV.SVNA5, SV.SVPZIP, SV.NONUK
FROM SCPF ACC
INNER JOIN GFPF CUS ON GFCPNC = SCAN
LEFT OUTER JOIN SXPF SEQ ON SXCUS = GFCUS AND SXPRIM = ''
LEFT OUTER JOIN SVPFClean SV ON SVSEQ = SXSEQ
LEFT OUTER JOIN BGPF ON BGCUS = GFCUS AND BGCLC = GFCLC
LEFT OUTER JOIN NEPF NE ON SCAB=NE.NEAB and SCAN=ne.NEAN and SCAS=ne.NEAS
LEFT OUTER JOIN SAPF SA ON SCAB=SAAB and SCAN=SAAN and SCAS=SAAS
WHERE
(SATCD>500 and
scsac='IV' and
scbal = 0 and
scai30<>'Y' and
scai14<>'Y' and
not exists(select * from v5pf where v5and=scan and v5bal<>0)) and
[Row] = 1
GROUP BY GFCUS, Ne.NEEAN, SCDLE, SAPOD, SATCD,
CUS.GFCUN, BGCFN1, BGCFN2, BGCFN3, SV.SVCSA,
SV.SVNA1, SV.SVNA2, SV.SVNA3, SV.SVNA4, SV.SVNA5, SV.SVPZIP, SV.NONUK
ORDER BY MAX(SCAN) ASC
You could encapsulate this within a subquery if you don't want to return the [Row] column.
you can user row_number to get top 1 row per customer
In the where clause need to return values with pos value as 1
sample query
row_number() over ( partition by GFCUS order by SAPOD desc) as pos

inner join with multiple records

i have 2 tables TblMemberDetails,TblMemberDetailsSub am using following sql queries to fetch records
QUERY 1
SELECT (TblMemberDetails.MemFname +' '+TblMemberDetails.MemMname +' '+
TblMemberDetails.MemLname)As Name,
TblStateMaster.StateName,
TblDistMaster.DistName,
TblTaluqaMaster.TaluqaName
FROM TblMemberDetails INNER JOIN TblStateMaster
ON TblMemberDetails.StateId = TblStateMaster.StateId
INNER JOIN TblDistMaster ON TblMemberDetails.DistId = TblDistMaster.DistId
INNER JOIN TblTaluqaMaster ON TblMemberDetails.TaluqaId = TblTaluqaMaster.TaluqaId
INNER JOIN TblMemberDetailsSub ON TblMemberDetails.MemId = TblMemberDetailsSub.MemId
WHERE (TblMemberDetailsSub.MemMode = 'Provider')
AND (TblMemberDetailsSub.CycleStatus = 'Uncompleted')
GROUP BY TblMemberDetailsSub.MemId, TblMemberDetails.MemId,
TblMemberDetails.MemFname, TblMemberDetails.MemMname,
TblMemberDetails.MemLname, TblStateMaster.StateName,
TblDistMaster.DistName, TblTaluqaMaster.TaluqaName
order by TblMemberDetailsSub.MemId Asc
QUERY 2
SELECT TblMemberDetailsSub.MemId, ISNULL(sum(TblMemberDetailsSub.Amount),0) AS TotalAmount,
TblMemberDetailsSub.PayRound, TblMemberDetailsSub.PlanName
FROM TblMemberDetailsSub
WHERE (TblMemberDetailsSub.MemMode = 'Provider')
AND (TblMemberDetailsSub.CycleStatus = 'Uncompleted')
GROUP BY TblMemberDetailsSub.MemId, TblMemberDetailsSub.PayRound,
TblMemberDetailsSub.PlanName, TblMemberDetailsSub.Amount
ORDER BY TblMemberDetailsSub.MemId Asc
I just want both table result in single set (i user union but it is not working)
how can i merge both queries for single result
Group by in first query is not significant if you have only one row for each memberId in
TblStateMaster ,TblDistMaster ,TblTaluqaMaster also you are not selecting any value from TblMemberDetailsSub in first query . One way to merge the two queries is as follows:
SELECT (TblMemberDetails.MemFname +
' '+
TblMemberDetails.MemMname +
' '+
TblMemberDetails.MemLname)As Name,
TblStateMaster.StateName,
TblDistMaster.DistName,
TblTaluqaMaster.TaluqaName,
T.MemId,
T.TotalAmount,
T.PayRound,
T.PlanName
FROM
TblMemberDetails
INNER JOIN TblStateMaster ON TblMemberDetails.StateId = TblStateMaster.StateId
INNER JOIN TblDistMaster ON TblMemberDetails.DistId = TblDistMaster.DistId
INNER JOIN TblTaluqaMaster ON TblMemberDetails.TaluqaId = TblTaluqaMaster.TaluqaId
Inner join (
select TblMemberDetailsSub.MemId,
ISNULL(sum(TblMemberDetailsSub.Amount),0)As TotalAmount,
TblMemberDetailsSub.PayRound,
TblMemberDetailsSub.PlanName
from TblMemberDetailsSub
WHERE (TblMemberDetailsSub.MemMode = 'Provider')
AND (TblMemberDetailsSub.CycleStatus = 'Uncompleted')
group by TblMemberDetailsSub.MemId,TblMemberDetailsSub.PayRound,TblMemberDetailsSub.PlanName,TblMemberDetailsSub.Amount
) T ON TblMemberDetails.MemId = T.MemId
order by T.MemId Asc