I have written the following query, that joins a table with already joined tables. I have basically used inner join using SQL Server. I am wondering how to modify the below code to use Left join rather than inner join?
The below query has three tables Blended, BOUND_TAB and RECORD
The second thing is, I also need to filter the results such that I use policies with deductibleinUSD > 0 in 'Blended' table or Primary_R Type = 'Deductible' and Primary_R Amount > 0 from the inner select. This should provide me the policies in my final results if either 'Blended' or 'BOUND_TAB' indicates that it has a deductible.
select
c.MPolicyNumber,
c.SNumber,
c.InsuredName,
c.EffDate,
c.Renewal,
c.GPremiumUSD,
c.Status,
c.deductibleinUSD, t.*
from
IT.dbo.Blended c
inner join
(select distinct
a.[Policy Number], a.[LOB],
a.[Primary_R Amount] as Bound_deductibles,
a.[Primary_R Type],
a.[EffDate] as CAS_EffDate
from
IT.dbo.BOUND_TAB a
inner join
IT.dbo.RECORD b on a.idxFile = b.[Bound Rater]
where
a.[Primary Retention Amount] > 0) t on t.[Policy Number] = c.MPolicyNumber
where
c.deductibleinUSD > 0
and c.ProductLine in ('Health','Cas')
order by
c.EffDate
Thanks in advance !
Without example data and an example of desired results, this is the best I can guess based on your question:
select
c.MPolicyNumber
, c.SNumber
, c.InsuredName
, c.EffDate
, c.Renewal
, c.GPremiumUSD
, c.Status
, c.deductibleinUSD
, t.*
from IT.dbo.Blended c
left join (
select distinct
a.[Policy Number]
, a.[LOB]
, a.[Primary_R Amount] as Bound_deductibles
, a.[Primary_R Type]
, a.[EffDate] as CAS_EffDate
from IT.dbo.BOUND_TAB a
inner join IT.dbo.RECORD b
on a.idxFile = b.[Bound Rater]
where a.[Primary Retention Amount] > 0
) as t
on t.[Policy Number] = c.MPolicyNumber
and c.ProductLine in ('Health','Cas')
and (c.deductibleinUSD > 0
or (Primary_R Type = 'Deductible'
and Bound_deductibles > 0
)
)
order by c.EffDate
Related
I have this query with 2 LEFT JOINS each with a sub-query.
The sub-queries should select the row with the latest date PointsChangeDate__c for a specific campaign e.g: PointsTypeCode__c = '1'.
Problem is that it is choosing what appears to be just random dates.
If I run just one JOIN / sub-query, then the result is correct, but when I add the 2nd JOIN / sub-query, then the results are incorrect and it seems to be pulling random dates.
I suspect my issue is with the type of JOIN I am using, but I cannot see why, because if I LEFT JOIN, then I am including all results (a._ContactKey) pulled from the first query and carrying that all the way through.
SELECT
a._ContactKey ContactId,
a.Full_Name_1__c Full_Name,
a.MC_Phone__c Mobile,
a.POSCustomerNumber__c POS_Customer_Number,
a.POSCustomerStatus__c POSCustomerStatus,
'IL' Locale,
a.Mobile_1__c Mobile_for_text,
g.TotalPoints__c TotalPoints_SourceMethod_1,
g.ValidUntil__c ValidUntil_SourceMethod_1,
g.date_1 PointsChangeDate__c_1,
h.TotalPoints__c TotalPoints_SourceMethod_2,
h.ValidUntil__c ValidUntil_SourceMethod_2,
h.date_2 PointsChangeDate__c_2
FROM
Contact_Salesforce AS a
LEFT JOIN
(SELECT
Contact__c,
TotalPoints__c,
ValidUntil__c,
MAX(PointsChangeDate__c) date_1
FROM
Member_points__c_Salesforce
WHERE
PointsTypeCode__c = '1'
GROUP BY Contact__c , TotalPoints__c , ValidUntil__c, PointsChangeDate__c) AS g ON a._ContactKey = g.Contact__c
LEFT JOIN
(SELECT Contact__c,
TotalPoints__c,
ValidUntil__c,
MAX(PointsChangeDate__c) date_2
FROM
Member_points__c_Salesforce
WHERE
PointsTypeCode__c = '2'
GROUP BY Contact__c , TotalPoints__c , ValidUntil__c, PointsChangeDate__c) AS h ON h.Contact__c = g.Contact__c
LEFT JOIN
SMS_Unsubscribe AS c ON REPLACE(CONCAT('972',
RIGHT(RTRIM(LTRIM(a.Mobile_1__c)), 9)),
'-',
'') = c.Mobile
LEFT JOIN
Member_Segments__c_Salesforce AS b ON b.Contact__c = a._ContactKey
WHERE
a.Mobile_1__c IS NOT NULL
AND c.Mobile IS NULL
AND a.POSCustomerStatus__c = '0'
AND b.IsActive__c = 'true'
GROUP BY a._ContactKey , a.Full_Name_1__c , a.MC_Phone__c , a.POSCustomerNumber__c , a.POSCustomerStatus__c , Locale , a.Mobile_1__c , a.Mobile_1__c , b.SegmentTypeID__c, b.SegmentTypeDescription__c , b.ToDate__c , g.TotalPoints__c , g.ValidUntil__c, g.date_1
,h.TotalPoints__c , h.ValidUntil__c, h.date_2
I want max dated rows for per GroupCode
I wrote this.
SELECT FH.BelgeNo AS FaturaNo
,FHD.UrunId
,FH.Tarih
,UG.Grup AS GrupKodu
,FHD.Kodu
,FHD.UrunAdi
,FHD.BirimFiyat
FROM FirmaHareketDetayi FHD
LEFT JOIN FirmaHareketleri FH ON FH.ID = FHD.HareketId
LEFT JOIN Urunler U ON U.UrunId = FHD.UrunId --and U.Kodu = FHD.Kodu
LEFT JOIN UrunGruplari UG ON UG.GrupId = U.GrupId
WHERE FHD.Kodu = '2S619H307CF'
AND FH.FirmaId = 2610
ORDER BY Tarih DESC
and results are like this
There are 2 PIERBURG rows.
is it possible to get only one PIERBURG ?
I mean max dated one (Tarih: Date column, GrupKodu: Group Code)
Notes: Table UrunGrupları: ProductGroups
Table FirmaHareketleri: FirmMovements
Table FirmaHareketDetayi: FirmMovementDetails (Connected with FirmMovements by HareketId (Foreign Key))
Sorry about my english :(
You can use window functions for this
;with cte as (
SELECT FH.BelgeNo AS FaturaNo
,FHD.UrunId
,FH.Tarih
,UG.Grup AS GrupKodu
,FHD.Kodu
,FHD.UrunAdi
,FHD.BirimFiyat
, row_number() over(partition by UG.Grup order by FH.Tarih desc) as rownum
FROM FirmaHareketDetayi FHD
LEFT JOIN FirmaHareketleri FH ON FH.ID = FHD.HareketId
LEFT JOIN Urunler U ON U.UrunId = FHD.UrunId --and U.Kodu = FHD.Kodu
LEFT JOIN UrunGruplari UG ON UG.GrupId = U.GrupId
WHERE FHD.Kodu = '2S619H307CF'
AND FH.FirmaId = 2610
)
select *
from cte
where rownum = 1
I have 2 tables item and memo. In item, itemId is the PK and the itid is the FK. In memo the memID is the PK.
I created a view:
SELECT
dbo.memo.memID, dbo.memo.fullname, dbo.memo.company,
dbo.memo.department, dbo.memo.MRnum, dbo.memo.date,
dbo.memo.returndate, dbo.memo.remarks,
dbo.memo.issuedby, dbo.memo.picture, dbo.item.itemID AS Expr1,
dbo.item.Itemnumber, dbo.item.description, dbo.item.qty,
dbo.item.unitofmeasure, dbo.item.itid
FROM
dbo.memo
INNER JOIN
dbo.item ON dbo.memo.memID = dbo.item.itid
WHERE
(dbo.memo.department = N'tsd')
and output is this
this is the output
I just want 1 output of the fullname, company, department, MRnum, date , remarks, issuedby every multiple rows of item
enter image description here
Hope you understand . thank you
You can use DISTINCT in your query.
See below
SELECT DISTINCT dbo.memo.memID, dbo.memo.fullname, dbo.memo.company, dbo.memo.department, dbo.memo.MRnum, dbo.memo.date, dbo.memo.returndate, dbo.memo.remarks, dbo.memo.issuedby, dbo.memo.picture, dbo.item.itemID AS Expr1, dbo.item.Itemnumber, dbo.item.description, dbo.item.qty, dbo.item.unitofmeasure, dbo.item.itid
FROM dbo.memo
INNER JOIN dbo.item ON dbo.memo.memID = dbo.item.itid
WHERE (dbo.memo.department = N'tsd')
i just want , 1 output of the fullname, company, department, MRnum,
date , remarks, issuedby with multiple rows of item
You could do this, use group by on required columns and take top 1
SELECT TOP 1
dbo.memo.fullname ,
dbo.memo.company ,
dbo.memo.department ,
dbo.memo.MRnum ,
dbo.memo.date ,
dbo.memo.remarks ,
dbo.memo.issuedby
FROM dbo.memo
INNER JOIN dbo.item
ON dbo.memo.memID = dbo.item.itid
WHERE ( dbo.memo.department = N'tsd' )
GROUP BY dbo.memo.fullname ,
dbo.memo.company ,
dbo.memo.department ,
dbo.memo.MRnum ,
dbo.memo.date ,
dbo.memo.remarks ,
dbo.memo.issuedby
Also you can use TOP like below if you are certain you get all duplicate records.
SELECT TOP 1 dbo.memo.memID, dbo.memo.fullname, dbo.memo.company, dbo.memo.department, dbo.memo.MRnum, dbo.memo.date, dbo.memo.returndate, dbo.memo.remarks, dbo.memo.issuedby, dbo.memo.picture, dbo.item.itemID AS Expr1, dbo.item.Itemnumber, dbo.item.description, dbo.item.qty, dbo.item.unitofmeasure, dbo.item.itid
FROM dbo.memo
INNER JOIN dbo.item ON dbo.memo.memID = dbo.item.itid
WHERE (dbo.memo.department = N'tsd')
Im not good at using Pivot but i think that's the only way to solve my Problem.
I have this SQL
SELECT DISTINCT ADR_Adressen.AdressNrADR
, LEFT(ADR_Adressen.Name, 3) AS Name
, LEFT(ADR_Adressen.Vorname, 3) AS Vorname
, CRM_Aufgaben.TerminVon
, LAG_Artikel.ArtikelNrLAG
, CRM_AufgabenLink.MitNrPRO
FROM ADR_Adressen
INNER JOIN PRO_Auftraege ON ADR_Adressen.AdressNrADR = PRO_Auftraege.Kunde
INNER JOIN CRM_Aufgaben ON PRO_Auftraege.AuftragNrPRO = CRM_Aufgaben.AuftragNrPRO
INNER JOIN CRM_Status ON CRM_Aufgaben.StatusCRM = CRM_Status.StatusCRM
INNER JOIN LAG_Artikel ON CRM_Aufgaben.ArtikelNrLAG = LAG_Artikel.ArtikelNrLAG
INNER JOIN ADR_GruppenLink ON ADR_Adressen.AdressNrADR = ADR_GruppenLink.AdressNrADR
INNER JOIN ADR_Gruppen ON ADR_GruppenLink.GruppeADR = ADR_Gruppen.GruppeADR
INNER JOIN CRM_AufgabenLink ON CRM_Aufgaben.AufgabenNrCRM = CRM_AufgabenLink.AufgabenNrCRM
WHERE { d '2016-03-07'} <= CRM_Aufgaben.TerminVon
AND { d '2016-03-11'} + 1 >= CRM_Aufgaben.TerminBis
AND CRM_AufgabenLink.MitNrPRO != 0
AND ADR_Gruppen.GruppeADR IN ( 'KIND' )
This is my result:
My wish is to get a Output like this:
The different Dates in TerminVon has to be Columns with the Values from ArtikelNrLAG+MitNrPRO. If the same AdressNrADR has more then one TerminVon on the same Date i have to make more rows. (Example where Name = Boc,Alt)
Can someone help me please =)
To PIVOT what you have, you can use a query similar to this.
SELECT AdressNrADR,
Name,
Vorname,
[2016-03-07],
[2016-03-08],
[2016-03-09],
[2016-03-10],
[2016-03-11]
FROM (
SELECT DISTINCT
ADR_Adressen.AdressNrADR,
LEFT(ADR_Adressen.Name,3) AS Name,
LEFT(ADR_Adressen.Vorname,3) AS Vorname,
CONVERT(VARCHAR(10), CRM_Aufgaben.TerminVon, 120) AS TerminVon, -- Convert date to yyyy-mm-dd format
LAG_Artikel.ArtikelNrLAG + '+' + CRM_AufgabenLink.MitNrPRO AS [Value], -- Combine column values
ROW_NUMBER() OVER
(PARTITION BY AdressNrADR,
LEFT(ADR_Adressen.Name,3),
LEFT(ADR_Adressen.Vorname,3),
CAST(CRM_Aufgaben.TerminVon AS DATE)
ORDER BY CRM_Aufgaben.TerminVon) Rn -- So we can get 1 row per time value
FROM ADR_Adressen
INNER JOIN PRO_Auftraege ON ADR_Adressen.AdressNrADR = PRO_Auftraege.Kunde
INNER JOIN CRM_Aufgaben ON PRO_Auftraege.AuftragNrPRO = CRM_Aufgaben.AuftragNrPRO
INNER JOIN CRM_Status ON CRM_Aufgaben.StatusCRM = CRM_Status.StatusCRM
INNER JOIN LAG_Artikel ON CRM_Aufgaben.ArtikelNrLAG = LAG_Artikel.ArtikelNrLAG
INNER JOIN ADR_GruppenLink ON ADR_Adressen.AdressNrADR = ADR_GruppenLink.AdressNrADR
INNER JOIN ADR_Gruppen ON ADR_GruppenLink.GruppeADR = ADR_Gruppen.GruppeADR
INNER JOIN CRM_AufgabenLink ON CRM_Aufgaben.AufgabenNrCRM = CRM_AufgabenLink.AufgabenNrCRM
WHERE { d '2016-03-07'} <= CRM_Aufgaben.TerminVon
AND { d '2016-03-11'} + 1 >= CRM_Aufgaben.TerminBis
AND CRM_AufgabenLink.MitNrPRO != 0
AND ADR_Gruppen.GruppeADR IN ('KIND')
) t
PIVOT (
MAX([Value])
FOR TerminVon IN ([2016-03-07],[2016-03-08],[2016-03-09],[2016-03-10],[2016-03-11])
) p
If you get that query to work. Your next step would be to make it Dynamic.
The difficult part of using t-sql's pivot functionality is that the output column names have to be hard coded. In your example we would need to know the value of each date and use that in the query in order to get the matching values by date. Fortunately other fine developers have experienced this frustration for us and have created scripts that will generate a dynamic pivot. I have included two links that will help you on your way.
https://www.mssqltips.com/sqlservertip/2783/script-to-create-dynamic-pivot-queries-in-sql-server/
http://sqlhints.com/2014/03/18/dynamic-pivot-in-sql-server/
Having issues getting a dataset to return with one date per client in the query.
Requirements:
Must have the recent date of transaction per client list for user
Will need have the capability to run through EXEC
Current Query:
SELECT
c.client_uno
, c.client_code
, c.client_name
, c.open_date
into #AttyClnt
from hbm_client c
join hbm_persnl p on c.resp_empl_uno = p.empl_uno
where p.login = #login
and c.status_code = 'C'
select
ba.payr_client_uno as client_uno
, max(ba.tran_date) as tran_date
from blt_bill_amt ba
left outer join #AttyClnt ac on ba.payr_client_uno = ac.client_uno
where ba.tran_type IN ('RA', 'CR')
group by ba.payr_client_uno
Currently, this query will produce at least 1 row per client with a date, the problem is that there are some clients that will have between 2 and 10 dates associated with them bloating the return table to about 30,000 row instead of an idealistic 246 rows or less.
When i try doing max(tran_uno) to get the most recent transaction number, i get the same result, some have 1 value and others have multiple values.
The bigger picture has 4 other queries being performed doing other parts, i have only included the parts that pertain to the question.
Edit (2011-10-14 # 1:45PM):
select
ba.payr_client_uno as client_uno
, max(ba.row_uno) as row_uno
into #Bills
from blt_bill_amt ba
inner join hbm_matter m on ba.matter_uno = m.matter_uno
inner join hbm_client c on m.client_uno = c.client_uno
inner join hbm_persnl p on c.resp_empl_uno = p.empl_uno
where p.login = #login
and c.status_code = 'C'
and ba.tran_type in ('CR', 'RA')
group by ba.payr_client_uno
order by ba.payr_client_uno
--Obtain list of Transaction Date and Amount for the Transaction
select
b.client_uno
, ba.tran_date
, ba.tc_total_amt
from blt_bill_amt ba
inner join #Bills b on ba.row_uno = b.row_uno
Not quite sure what was going on but seems the Temp Tables were not acting right at all. Ideally i would have 246 rows of data, but with the previous query syntax it would produce from 400-5000 rows of data, obviously duplications on data.
I think you can use ranking to achieve what you want:
WITH ranked AS (
SELECT
client_uno = ba.payr_client_uno,
ba.tran_date,
be.tc_total_amt,
rnk = ROW_NUMBER() OVER (
PARTITION BY ba.payr_client_uno
ORDER BY ba.tran_uno DESC
)
FROM blt_bill_amt ba
INNER JOIN hbm_matter m ON ba.matter_uno = m.matter_uno
INNER JOIN hbm_client c ON m.client_uno = c.client_uno
INNER JOIN hbm_persnl p ON c.resp_empl_uno = p.empl_uno
WHERE p.login = #login
AND c.status_code = 'C'
AND ba.tran_type IN ('CR', 'RA')
)
SELECT
client_uno,
tran_date,
tc_total_amt
FROM ranked
WHERE rnk = 1
ORDER BY client_uno
Useful reading:
Ranking Functions (Transact-SQL)
ROW_NUMBER (Transact-SQL)
WITH common_table_expression (Transact-SQL)
Using Common Table Expressions