Why is my Left Not pulling all the dates even though they exist on the other table SQL - sql

I have a table without dates and wish to join on the table with dates.I am doing a left join on id and bn_number. The id can have more than one dates , i obviously want the latest date from the other tables as it has more than one date for each id. i am not sure how to get all the dates at least then i can be able to choose the latest one.
select Reg_Property_id,a.Bnd_nbr,account_balance,abs(account_balanc‌​e) as Bond_Balance,a.Bnd_regDate
into #Jan2014ValidFin
from #Jan2014Valid aa
left join Pr_analytics..bond a
on aa.Reg_Property_id=a.Prop_id
and aa.bnd_nbr=a.Bnd_nbr
where aa.reg_property_id is not null
SQL
Please assist.

Use the ROW_NUMBER() window function to get the most recent date:
SELECT c.*
FROM (
SELECT a.cols, b.cols, ROW_NUMBER() OVER (PARTITION BY b.colID1,b.colID2 ORDER BY b.theDate DESC) AS rn
FROM a
LEFT OUTER JOIN b ON a.col1 = b.col1
AND a.col2 = b.col2
) c
WHERE c.rn = 1

A simple group by should do the trick:
SELECT
Reg_Property_id -- What table is this from?
,a.Bnd_nbr
,account_balance -- What table is this from?
,abs(account_balance) as Bond_Balance -- What table is this from?
,max(a.Bnd_regDate) as Bnd_regDate
into #Jan2014ValidFin
from #Jan2014Valid aa
left join Pr_analytics..bond a
on aa.Reg_Property_id = a.Prop_id
and aa.bnd_nbr = a.Bnd_nbr
where aa.reg_property_id is not null
group by
Reg_Property_id
,a.Bnd_nbr
,account_balance
,abs(account_balance)
Note that if there are no dates (a.Bnd_regDate), you will get NULL
Note also that if any of the values marked "what table is this from" are found in #Jan2014Valid, you will need to either aggregate them (max, sum, etc.) or include them in the group by clause--I can't tell which, from the information provided.

Related

look up dynamic value from range in another table

I have 2 tables. The first one is a detail table with years and actual limit values. The second table has max control limits but only for certain years.
Table 1 & 2
What I want to do is list all of the detail records but pull in the values of the control limits if the year is less than the next one listed in the control table.
Desired results:
results
I have tried this query but it duplicates 2015, 2016 and 2017.
SELECT d.id, d.yeard, d.value, c.Column1
FROM detailTbl d
RIGHT OUTER JOIN controlTbl c ON d.dated <= c.datec
You may use Row_Number() function as the following to remove duplicates:
with cte as
(
Select D.id,D.yeard,D.val, C.limitVal,
row_number() over (partition by D.id order by C.yeard desc) as rn from
detailTbl D left join controlTbl C
on D.yeard>=C.yeard
)
Select B.id,B.yeard,B.val,B.limitVal from
cte B where B.rn=1 order by B.id
See a demo on MySQL 8.0 from here.

SQL joined tables are causing duplicates

So table A is an overall table of policy_id information, while table b is policy_id's with claims attached. Not all of the id's in A exist in B, but I want to join the two tables and sum(total claims).
The issue is that the sum is way higher than the actual sum within the table itself.
Here is what I've tried so far:
select a.policy_id, coalesce(sum(b.claim_amt), 0)
from database.table1 as a
left join database2.table2 as b on a.policy_id = b.policy_id
where product_code = 'CI'
group by a.policy_id
The id's that don't exist in b show up just fine with a 0 next to them, it's the ones that do exist where the claim_amt's seem like they're being duplicated heavily in the sum.
I suspect your policy_id in table1 are not unique and that leads to the doubled,tripled ,etc. amounts
You could aggregate the sums from table2 in a CTE to get around this.
WITH CTE AS (
SELECT
policy_id
coalesce(sum(claim_amt), 0) as sum_amt
FROM database2.table2
group by policy_id
)
select a.policy_id, b.sum_amt
from database.table1 as a
left join CTE as b on a.policy_id = b.policy_id
where product_code = 'CI'

SQL tables joined with max

I'm working with two tables. I have a full list of groups in table A, and a list of each group member that has been reviewed in table B. So table B is a log of all review records for those members for each group.
select a.Group_Name, Max(b.Request_Review_Date)
From GroupTable a
Left Outer Join GroupReviews b ON a.Group_Name = b.Group_Name
Group By a.Group_Name
What I am trying to return is the full list of groups from table A, and find the latest review date from table B for each of those groups.
I have researched and tried all or most of the inner & outer joins, apply methods....but its just not giving me the results. Can anyone point me in the right direction? Or am I having to bring back two result sets and compare in my ASP code-behind?
Try a CTE then join back to it
WITH Recent AS
(
select group_name, max(Request_Review_Date) AS 'MaxReviewDate'
from GroupReviews
group by group_name
)
select a.group_name, MaxReviewDate
from GroupTable a left join Recent
on group_name = a.group_name
if you need the value for max for all the a.group name rows the ypu should join the subquery for max date
select a.Group_Name, t.max_date
left join (
select b.Group_Name, Max(b.Request_Review_Date) max_date
from GroupReviews b
Group By b.Group_Name
) t on t.Group_Name = a.Group_Name

How to select the most recent data from SQL joining 3 tables?

I have 3 tables. I need to join the (AGENT table) from (DATA table) by column RANKDATA. There may be multiple entries in the DATA table. I need to select the most recent based on the DATE, then get the CODE_ID and join in CODE table.
Here's my code. I tried to use Max(D.DATE) but I got an error. My only problem, I don't know how to group it by the most recent date.
select A.ID, A.NAME, C.CODE_NAME, D.DATE
from Agent A
JOIN Data D ON A.RANKDATA = D.RANKDATA
JOIN CODE C ON D.CODE_ID = C.CODE_ID
output
I'm not quite clear on what your results are supposed to be from your image, bu t an alternative to doing this with a group by might be to use row_number. row_number basically projects a column with an incrementing integer (1,2,3,...n) over your rows. You can "partition" the function in the same way you would a group by. In this case, I partitioned it by a.RankData, but that was sort of a guess at what you wanted. The order by defines in what order the row numbering will appear. In this case, I've ordered it by d.[date] descending so the most recent date for every a.RankData will be the number 1. Finally, I turn all that into a subquery so I can put the new column in a where clause and just skim off those where RID = 1 (i.e the date is the max date).
select *
from (select
RID = row_number() over(partition by a.RankData order by d.[date] desc),
A.ID,
A.NAME,
C.CODE_NAME,
D.DATE
from Agent A
inner join [Data] D
on A.RANKDATA = D.RANKDATA
inner join CODE C
on D.CODE_ID = C.CODE_ID) a
where a.RID = 1
You could try using a CROSS APPLY, as an additional option.
SELECT A.ID, A.NAME, T.CODE_NAME, T.DATE
FROM Agent A
CROSS APPLY
(SELECT TOP 1 C.CODE_NAME, D.DATE
FROM
Data D JOIN CODE C ON D.CODE_ID = C.CODE_ID
WHERE A.RANKDATA = D.RANKDATA
ORDER BY D.DATE DESC) T
An image helps to visualize. But if you need time from others to help you, it would definitely be useful if you include a simple script to create your test data:
Something like this:
CREATE TABLE Agent (ID INT, NAME VARCHAR(30) ,RANKDATA INT)
INSERT INTO Agent
VALUES (1,'Mark',12), (2,'Joe',13), (3,'Steve',11), (4,'Sam',10)
CREATE TABLE DATA (ID int, RANKDATA int, CODE_ID VARCHAR(2), DATE datetime)
INSERT INTO DATA
VALUES (1,12,'01','20170901 2:30'), (2,13,'02','20170901 6:30'),
(3,11,'03','20170901 4:30'), (4,10,'02','20170901 1:30'),
(5,10,'03','20170901 2:50'), (6,12,'02','20170901 5:30')
CREATE TABLE CODE(ID int, CODE_ID varchar(2), CODE_NAME Varchar(15))
INSERT INTO CODE
VALUES (1,'01','RANK 1'), (2,'02','RANK 2'), (3,'03','RANK 3')

SQL Inner Join using Distinct and Order by Desc

table a.
Table b . I have two tables. Table A has over 8000+ records and continues to grow with time.
Table B has only 5 or so records and grows rarely but does grow sometimes.
I want to query Table A's last records where the Id for Table A matches for Table B. The problem is; I am getting all the rows from Table A. I just need the ones where Table A and B match once. These are unique Id's when a new row is inserted into table B and never get repeated.
Any help is most appreciated.
SELECT a.nshift,
a.loeeworkcellid,
b.loeeconfigworkcellid,
b.loeescheduleid,
b.sdescription,
b.sshortname
FROM oeeworkcell a
INNER JOIN dbo.oeeconfigworkcell b
ON a.loeeconfigworkcellid = b.loeeconfigworkcellid
ORDER BY a.loeeworkcellid DESC
I am assuming you want to get the only the lastest (as you said) row from the TableA but JOIN giving you all the rows.You can use the Row_Number() to get the rownumber and then apply the join and filter it with the Where clause to select only the first row from the JOIN. So what you can try as below,
;WITH CTE
AS
(
SELECT * , ROW_NUMBER() OVER(PARTITION BY loeeconfigworkcellid ORDER BY loeeworkcellid desc) AS Rn
FROM oeeworkcell
)
SELECT a.nshift,
a.loeeworkcellid,
b.loeecoonfigworkcellid,
b.loeescheduleid,
b.sdescription,
b.sshortname
FROM CTE a
INNER JOIN dbo.oeeconfigworkcell b
ON a.loeeconfigworkcellid = b.loeeconfigworkcellid
WHERE
a.Rn = 1
You need to group by your data and select only the data having the condition with min id.
SELECT a.nshift,
a.loeeworkcellid,
b.loeecoonfigworkcellid,
b.loeescheduleid,
b.sdescription,
b.sshortname
FROM oeeworkcell a
INNER JOIN dbo.oeeconfigworkcell b
ON a.loeeconfigworkcellid = b.loeeconfigworkcellid
group by
a.nshift,
a.loeeworkcellid,
b.loeecoonfigworkcellid,
b.loeescheduleid,
b.sdescription,
b.sshortname
having a.loeeworkcellid = min(a.loeeworkcellid)