Original column name from T-SQL query that yields columns AFTER the original column name was reclassified - sql-server

I have a relatively standard sql query with several table joins and where clauses that all relate a loan after it has been reclassified to ORE (Other Real Estate Owned). I am trying to list the value of one of the ORIGINAL fields (category) that has been changed now that it is ORE.
Say the original category was 1 for 'Consumer' but once the loan goes to ORE, the category is a 12 which includes ALL original categories (1,2,3,4)
Therein lies the problem - I need to show the ORE loans for only say categories 1 & 2. Nothing I've tried works - I'm assuming because the where clause at the bottom of the query specifies that I need various fields that all tie to the ORE status but NOT to the original categories. I've tried subqueries (don;t work because they are 'above' the main query's where clause...
Any general guidance would be greatly appreciated. Here's the query and the subquery below it:
SELECT
A.ACCTNO
E.SNAME,
B.OREO_ID,
A.OREODATE,
GC.CATEGORY
FROM
DBO.LOAN_SYSTEM AS A
LEFT OUTER JOIN DBO.ORE AS B
ON A.OREO_ID = B.OREO_ID
LEFT OUTER JOIN DBO.LOAN_TITLE AS C
ON A.OREO_ID = C.OREO_ID AND C.SEQ = 1
LEFT OUTER JOIN (SELECT * FROM DBO.LOAN_FC WHERE ISDELETED = 0 AND ISDISMISSED IS NULL) AS D
ON A.OREO_ID = D.OREO_ID
LEFT OUTER JOIN DBO.TBL_GROUP_CODES GC
ON E.[GROUP] = GC.GROUP_CODE
WHERE
D.FC_ID IS NOT NULL AND C.FORECLOSUREDATE IS NOT NULL AND GC.CATEGORY IN (1,2) --DOESN'T WORK BECAUSE ONCE IN OREO = 12
AND
E.STATUS NOT IN (2,8)
--SUBQUERY GETS ORIGINAL CATEGORY
SELECT
B.ACCTNO, C.CATEGORY
FROM DBO.LOAN_SYSTEM A
LEFT OUTER JOIN DBO.LOAN_DAILY_INFO B
ON B.ACCTNO = A.ACCTNO
AND B.TYPE = A.TYPE
LEFT OUTER JOIN DBO.TBL_GROUP_CODES C
ON C.GROUP_CODE = B.[GROUP]
LEFT OUTER JOIN DBO.TBL_LOAN_TYPES D
ON D.TYPE = A.TYPE
WHERE B.STATUS NOT IN (2,8)
AND C.CATEGORY IN (1,2)

I'm not 100% sure what you're trying to do here.. but you might need to use EXISTS here.
SELECT A.ACCTNO,
E.SNAME,
B.OREO_ID,
A.OREODATE,
GC.CATEGORY
FROM DBO.LOAN_SYSTEM AS A
LEFT OUTER JOIN DBO.ORE AS B ON A.OREO_ID = B.OREO_ID
LEFT OUTER JOIN DBO.LOAN_TITLE AS C ON A.OREO_ID = C.OREO_ID
AND C.SEQ = 1
LEFT OUTER JOIN (SELECT * FROM DBO.LOAN_FC WHERE ISDELETED = 0 AND ISDISMISSED IS NULL
) AS D ON A.OREO_ID = D.OREO_ID
LEFT OUTER JOIN DBO.TBL_GROUP_CODES GC ON D.[GROUP] = GC.GROUP_CODE
WHERE D.FC_ID IS NOT NULL
AND C.FORECLOSUREDATE IS NOT NULL
AND EXISTS (
SELECT 1
FROM DBO.LOAN_DAILY_INFO F
JOIN DBO.TBL_GROUP_CODES G ON G.GROUP_CODE = F.[GROUP]
WHERE F.STATUS NOT IN (2,8)
AND G.CATEGORY IN (1,2)
AND F.ACCTNO = A.ACCTNO
AND F.TYPE = A.TYPE
)
AND D.STATUS NOT IN (2,8)

Related

Find third largest quote ever created for each of the accounts in the EC1 area

Can anyone help I'm new to SQL and trying to figure out the below question see image for the table structure;
Question = Select account name, contact last name, case number, quote number, quote date and quote value for the f third-largest quote ever created for each of the accounts in the EC1 area
So far I got;
Select
a.accountname, cc.lastname, c.casenumber,
q.quotenumber, q.quotedate, q.quotevalue
from
TBL_Quote q
Left join
TBL_case c On q.caseid = c.caseid
Left join
tbl_contact cc On c.contactID = cc. contactID
Left join
tbl_account a On a.accountid = cc.accountid
Where
left(a.postcode, 3) like 'EC1'
and for the third:
SELECT TOP 1 value
FROM
(SELECT DISTINCT TOP 3 value
FROM tbl_quote
ORDER BY value DESC) a
ORDER BY value
I can't seem to combine the top 3 and the query is it best to overpartion by ?
I would suggest joins and a row-limiting clause:
select ac.accountName, co.lastName, ca.caseNumber, qu.quoteNumber
from tbl_account ac
inner join tbl_contact co on co.accountId = ac.accountId
inner join tbl_case ca on ca.contactId = co.contactId
inner join tbl_quote qu on qu.caseId = ca.quoteId
where ac.postcode like 'EC1%'
order by len(qu.value) desc
offset 2 rows fetch next 1 row only

Update does not add the correct values

My select statement returns the ids from the tables I have joined correctly(393, starting at 92 and going up 484, its not a PK field, so some ids can be used more then once) there is a total of 550 rows I need to update, when I run the update it only adds the number 92 to the table for all 550 rows.
update movements set [location] = locaID.id FROM (
SELECT
lo.id
FROM [Harvest_Transactions] ht
left join [Harvest_Master_Shift] hms on ht.Harvest_Master_id = hms.Harvest_Master_id
left join [Greenhouse_Troughs] gt on ht.Trough = gt.Greenhouse_Trough_id
left join [batches] b on b.name = hms.Batch_id
left join [phases] p on p.batch = b.id and p.[type] = 3
left join #loc lo on lo.name = gt.Trough_No and lo.area = gt.SQM_per_Trough and lo.Bay_id = gt.Bay_id
where ht.Number_of_Plants_Harvested != 0 and (hms.CreatedOn <= '2020-02-05 09:33:00.000' OR hms.CreatedOn is null )
)locaID where product = 14
what am I missing so it updates with the correct values?
My first impression of your query is that only the rows with product = 14 in movements table will be updated with the single value coming from the subquery.
If you want to update the values based on another derived table, you need some way to link the rows together - i.e a JOIN between your table being updated and the table that holds the other data (see here )
What is the common column between movements and
SELECT
lo.id
FROM [Harvest_Transactions] ht
left join [Harvest_Master_Shift] hms on ht.Harvest_Master_id = hms.Harvest_Master_id
left join [Greenhouse_Troughs] gt on ht.Trough = gt.Greenhouse_Trough_id
left join [batches] b on b.name = hms.Batch_id
left join [phases] p on p.batch = b.id and p.[type] = 3
left join #loc lo on lo.name = gt.Trough_No and lo.area = gt.SQM_per_Trough and
lo.Bay_id = gt.Bay_id
where ht.Number_of_Plants_Harvested != 0 and (hms.CreatedOn <= '2020-02-05
09:33:00.000' OR hms.CreatedOn is null )
The rough syntax shouldI think be
UPDATE movements
set [location] = locaID.id
FROM movements
JOIN (
SELECT
lo.id
FROM [Harvest_Transactions] ht
left join [Harvest_Master_Shift] hms on ht.Harvest_Master_id = hms.Harvest_Master_id
left join [Greenhouse_Troughs] gt on ht.Trough = gt.Greenhouse_Trough_id
left join [batches] b on b.name = hms.Batch_id
left join [phases] p on p.batch = b.id and p.[type] = 3
left join #loc lo on lo.name = gt.Trough_No and lo.area = gt.SQM_per_Trough and
lo.Bay_id = gt.Bay_id
where ht.Number_of_Plants_Harvested != 0 and (hms.CreatedOn <= '2020-02-05
09:33:00.000' OR hms.CreatedOn is null )
) locaID
ON movements.<some column> = locaID.<some column>

Group the count values

I want to get the count of property and building and building is linked with property. Below is the query I tried:
select
PT.PropertyTypeName,
Count(PropertyID) as ProperyCount,
Isnull((Select count(B.BuildingID)
from Building B
join Property P1
on B.PropertyID=P1.PropertyID
where B.PropertyID =P.PropertyID), 0) as BuildingsCount
from Property P
join PropertyType PT
on PT.PropertyTypeID = P.PropertyTypeID
left join AssetToFund AF
on AF.AssetID = P.AssetID
left join Fund F
on F.FundID = AF.FundID
left join Asset A
on A.AssetID = P.AssetID
left join Client C
on C.ClientID = F.ClientID
where C.ClientId=10000001
group by PT.PropertyTypeName,P.PropertyID
I expect values group of type
and I want to group the count with out duplicate of property-type name
sry for bad English.
Try to use the SUM() function on this subquery
Returns the sum of all the values, or only the DISTINCT values, in the expression. SUM can be used with numeric columns only. Null values are ignored.
MSDN
SUM(Select count(B.BuildingID)
from Building B
join Property P1
on B.PropertyID=P1.PropertyID
where B.PropertyID = P.PropertyID)
When you use GROUP BY then it groups data by columns which you've written in GROUP BY statement. You've written :
GROUP BY PT.PropertyTypeName,P.PropertyID`
it means that SQL Engine will get all unique combinations of PropertyTypeName, PropertyID. However, you want just unique PropertyTypeName. So write just this field into GROUP BY statement:
GROUP BY PT.PropertyTypeName
So complete query will look like this:
select
PT.PropertyTypeName,
Count(PropertyID) as ProperyCount,
Isnull((Select count(B.BuildingID)
from Building B
join Property P1
on B.PropertyID=P1.PropertyID
where B.PropertyID =P.PropertyID), 0) as BuildingsCount
from Property P
join PropertyType PT
on PT.PropertyTypeID = P.PropertyTypeID
left join AssetToFund AF
on AF.AssetID = P.AssetID
left join Fund F
on F.FundID = AF.FundID
left join Asset A
on A.AssetID = P.AssetID
left join Client C
on C.ClientID = F.ClientID
where C.ClientId=10000001
group by PT.PropertyTypeName

IS NULL being ignored

I am trying to run a query in T-SQL to pull back a data set based on a column being null.
This is a simplified version of the code:
SELECT
T1.Col1, T1.Col2,
T1.Col3, T1.Col4
FROM
table1 AS T1
INNER JOIN
table2 AS T2 ON T1.Col2 = T2.Col3
WHERE
T2.Col4 IS NULL
Problem is, the result includes rows where T2.Col4 are NULL and also not NULL, it's like the WHERE clause doesn't exist.
Any ideas would be greatly
UPDATE - full version of code:
SELECT
M.ref
,C.cname
,CL.clname
,C.ccity
,M.productLine
,M.code
,CL.date
,M.dept
,DPT.group
,TK2.tkname
,TK2.tkdept
FROM DB.dbo.manage AS M
OUTER JOIN DB.dbo.ClientManageRelationship AS CMR
ON CMR.RelatedEntityID = M.EntityID
OUTER JOIN DB.dbo.Client AS C
ON C.EntityID = CMR.EntityID
INNER JOIN DB.dbo.ManageCustomerRelationship AS MCR
ON MCR.EntityID = M.EntityID
INNER JOIN DB.dbo.Customer AS CL
ON CL.EntityID = MCR.RelatedID
INNER JOIN DB.dbo.timek AS TK
ON TK.tki = M.tkid
LEFT JOIN (SELECT Group = division, [Department] = newdesc, deptcode FROM DB.csrt.vw_rep_p_l_dept) AS DPT
ON tkdept = DPT.dept
LEFT JOIN (SELECT Name = TK2.tkfirst + ' ' + TK2.tklast, TK2.tki, TK2.dept, TK2.loc FROM DB.dbo.timek as TK2 WITH(NOLOCK)) AS TK2
ON TK2.tki = M.tkid
WHERE DPT.Department = 'Casualty'
AND UPPER (C.ClientName) LIKE '%LIMITED%'
AND CL.date > '31/12/2014'
AND CL.Date IS NULL
AND TK.tkloc = 'loc1' OR TK.tkloc = 'loc2'
ORDER BY M.ref
My first answer would be because you're using INNER JOIN. This only returns matches between the 2 tables. TRY FULL OUTER JOIN which will return all values regardless of matches and will include NULLS.
If you were looking to return all rows regardless of matches including NULLS from only one of the tables then use RIGHT or LEFT JOIN.
Say i had 2 tables ('Person' and 'Figure'). Not every person may have entered a figure on any one day. But an example may be i want to return all people regardless of whether they entered a figure or not on a certain day.
My initial approach to this would be a LEFT join because i want to return of all the people(left table) regardless of there being any matches in the figure table(right table)
FROM Person P
LEFT JOIN Figure F
ON P.ID = F.ID
This would produce a result such as
Name Figure
Sam 20
Ben 30
Matt NULL
Simon NULL
Whereas,
An inner join would produce only matching values not including nulls
Name Figure
Sam 20
Ben 30
Left join works the same way as right join but in the opposite direction. This is most likely the problem you were facing. But i hope this helped
I think the problem is in the last part of the where condition.
You should use brackets.
`WHERE DPT.Department = 'Casualty'
AND UPPER (C.ClientName) LIKE '%LIMITED%'
AND CL.date > '31/12/2014'
AND CL.Date IS NULL
AND (TK.tkloc = 'loc1' OR TK.tkloc = 'loc2')`
or
`WHERE DPT.Department = 'Casualty'
AND UPPER (C.ClientName) LIKE '%LIMITED%'
AND CL.date > '31/12/2014'
AND CL.Date IS NULL
AND TK.tkloc IN ('loc1', 'loc2')`

JOIN codition in SQL Server

After applying join condition on two tables I want records which is maximum among records of left table
My query
SELECT a1.*,
t.*,
( a1.trnratefrom - t.trnratefrom )AS minrate,
( a1.trnrateto - t.trnrateto ) AS maxrate
FROM (SELECT a.srno,
trndate,
b.trnsrno,
Upper(Rtrim(Ltrim(b.trnstate))) AS trnstate,
Upper(Rtrim(Ltrim(b.trnarea))) AS trnarea,
Upper(Rtrim(Ltrim(b.trnquality))) AS trnquality,
Upper(Rtrim(Ltrim(b.trnlength))) AS trnlength,
Upper(Rtrim(Ltrim(b.trnunit))) AS trnunit,
b.trnratefrom,
b.trnrateto,
a.remark,
entdate
FROM mstprodrates a
INNER JOIN trnprodrates b
ON a.srno = b.srno)a1
INNER JOIN (SELECT c.srno,
trndate,
d.trnsrno,
Upper(Rtrim(Ltrim(d.trnstate))) AS trnstate,
Upper(Rtrim(Ltrim(d.trnarea))) AS trnarea,
Upper(Rtrim(Ltrim(d.trnquality))) AS trnquality,
Upper(Rtrim(Ltrim(d.trnlength))) AS trnlength,
Upper(Rtrim(Ltrim(d.trnunit))) AS trnunit,
d.trnratefrom,
d.trnrateto,
c.remark,
entdate
FROM mstprodrates c
INNER JOIN trnprodrates d
ON c.srno = d.srno) AS t
ON a1.trnstate = t.trnstate
AND a1.trnquality = t.trnquality
AND a1.trnunit = t.trnunit
AND a1.trnlength = t.trnlength
AND a1.trnarea = t.trnarea
AND a1.remark = t.remark
WHERE t.srno = (SELECT MAX(srno)
FROM a1
WHERE srno < a1.srno)
If you mean to say,
you want Records exist in Left table but not in right then use LEFT OUTER JOIN.

Resources