Show Unique values only - sql

I am using SQL Server 2019 and looking for a way to show ONLY the latest value for each AOC based on its latest FW_Version. Here is my query I have so far but this shows everything:
SELECT DISTINCT
dbo.Model.ModelName AS AOC,
dbo.Chipset.Chipset,
dbo.FormFactor.FormFactor AS Form_Factor,
dbo.ProductRelease.ECO AS Release,
dbo.ProductRelease.Date AS Release_Date,
dbo.Intel.FWVersion AS FW_Version,
dbo.Intel.ETRACKID
FROM
dbo.Intel
INNER JOIN dbo.ProductRelease ON dbo.Intel.ProductReleaseID = dbo.ProductRelease.ID
INNER JOIN dbo.Model ON dbo.ProductRelease.ModelID = dbo.Model.ID
INNER JOIN dbo.FormFactor ON dbo.Model.FormFactorID = dbo.FormFactor.ID
INNER JOIN dbo.Chipset ON dbo.Intel.ControllerID = dbo.Chipset.ControllerID AND dbo.Intel.ChipsetID = dbo.Chipset.ID
ORDER BY
dbo.Model.ModelName,
dbo.Intel.FWVersion DESC,
dbo.ProductRelease.Date DESC
What I would like to show ONLY items marked in yellow... How can I make this happen?
Here is the list of my Tables which are joined based on their corresponding ID's
Table 1: Model
ID (Primary Key)
ModelName nvarchar(50)
FormFactorID int
Table 2: FormFactor
ID (Primary Key)
FormFactor nvarchar(15)
Table 3: ProductRelease
ID (Primary Key)
ModelID int
Date date
ECO nvarchar(10)
Table 4: Intel
ID (Primary Key)
ProductReleaseID int
ChipsetID int
FWVersion nvarchar(10)
ETRACKID nvarchar(15)
Table 5: Chipset
ID (Primary Key)
Chipsetnvarchar(20)

One method uses window functions:
SELECT *
FROM (
SELECT
dbo.Model.ModelName AS AOC,
dbo.Chipset.Chipset,
dbo.FormFactor.FormFactor AS Form_Factor,
dbo.ProductRelease.ECO AS Release,
dbo.ProductRelease.Date AS Release_Date,
dbo.Intel.FWVersion AS FW_Version,
dbo.Intel.ETRACKID,
ROW_NUMBER() OVER(PARTITION BY dbo.Model.ModelName ORDER BY dbo.ProductRelease.Date DESC) rn
FROM
dbo.Intel
INNER JOIN dbo.ProductRelease ON dbo.Intel.ProductReleaseID = dbo.ProductRelease.ID
INNER JOIN dbo.Model ON dbo.ProductRelease.ModelID = dbo.Model.ID
INNER JOIN dbo.FormFactor ON dbo.Model.FormFactorID = dbo.FormFactor.ID
INNER JOIN dbo.Chipset ON dbo.Intel.ControllerID = dbo.Chipset.ControllerID AND dbo.Intel.ChipsetID = dbo.Chipset.ID
) t
WHERE rn = 1
ORDER BY AOC

Related

remove Union from query

I have query to get category and subcategories of same category. I used below query:
Select Id from category where name like '%events%' and deleted = 0 and published = 1
UNION
SELECT Id from category where parentcategoryid = (Select id from category where name like '%events%' and deleted = 0 and published = 1)
I do not want to use UNION, want to use Join only. But not getting how i can achieve. Below is the table structure. Please help me. thanks in Advance
The following might solve your problem:
DECLARE #t TABLE (id int, name varchar(20), parentcatid varchar(200))
insert into #t values(23,'Christmas', 34)
,(29,'Birthday', 34)
,(31,'New year', 34)
,(34,'Events', 0)
,(35,'gfrhrt', 0)
;WITH cte AS(
Select Id from #t
where name like '%events%' --and deleted = 0 and published = 1
),
cte2 AS (
SELECT a.id AS tId, cpa.id, cId2.id AS idPa
from #t a
LEFT JOIN cte AS cId ON cId.Id = a.Id
FULL OUTER JOIN #t AS cPa ON cPa.parentcatid = cId.Id
LEFT JOIN cte cId2 ON cId2.id = cPa.id
WHERE cId.Id IS NOT NULL OR cPa.Id IS NOT NULL
)
SELECT id
FROM cte2
WHERE tId IS NOT NULL
OR id = idPa
The idea is to get all required IDs within the cte and then get all categories, where either ID oder ParentID match the IDs from the cte. However, depending on the size of your table, you might want to add further filters to the cte.

how can i get the latest record published by each singer

I have 3 tables
table 1 : songs
-songname varchar
-singerlabel varchar
-date date
-category varchar
table 2 : singer
-singerlabel varchar
-singer# varchar
table 3 : singerNote
-singer# varchar
-firstname varchar
-lastname varchar
table 1 is connected to table 2 using singerlabel.
table 2 is connected to table 3 using singer#.
With this query:
select singerlabel, max(date) maxdate
from songs
group by singerlabel
you get the max date of each singerlabel, and then join to the other 3 tables:
select sn.firstname, sn.lastname, songs.songname
from (
select singerlabel, max(date) maxdate
from songs
group by singerlabel
) s inner join singer
on singer.singerlabel = s.singerlabel
inner join singernote sn
on sn.singer = singer.singer
inner join songs
on songs.singerlabel = s.singerlabel and songs.date = s.maxdate
If your RDBMS supports window functions, this can be achieved with ROW_NUMBER() :
SELECT x.*
FROM (
SELECT
si.*, sn.first_name, sn.last_name, so.songname, so.date, so.category
ROW_NUMBER() OVER(PARTITION BY so.singerlabel ORDER BY so.date DESC) rn
FROM singer si
INNER JOIN singerNote sn ON sn.singer# = si.singer#
INNER JOIN songs so ON so.singerlabel = si.singerlabel
) x WHERE x.rn = 1
Without window function, you can use a correlated subquery with a NOT EXISTS condition to ensure that you are joining with the most recent song :
SELECT si.*, sn.first_name, sn.last_name, so.songname, so.date, so.category
FROM
singer si
INNER JOIN singerNote sn
ON sn.singer# = si.singer#
INNER JOIN songs so
ON so.singerlabel = si.singerlabel
AND NOT EXISTS (
SELECT 1
FROM songs so1
WHERE so1.singerlabel = si.singerlabel AND so1.date > so.date
)

TSQL not pulling in complete data set

I have a complicated stored procedure that worked great until the client wanted to change it.
I am not great with complicated TSQL so I have no idea what is wrong with my code.
Here is the situation. I have three temp tables, Cost, Adjustments, and Payments.
In the end I merge all these tables together in a report table. The problem I am having is even if one or even two of these tables are null, as long as one table has data I need that data to show. I currently have it set up with full outer joins but I'm still not getting the full list, I'm missing probably....50 ish records that should be there.
Can anyone look at this code and tell me what the heck I'm doing wrong? I'm bringing all the data together on #ThisReportAll
UPDATE: So I removed the having clause to see what was going on, and the data for the overdue balance is returning null. So the math isn't...mathing correctly, any ideas?
CODE
CREATE TABLE #BalanceAdjustmentsAll (CustomerId int, Amount decimal(20,2));
CREATE TABLE #AnimalCostsAll (thisIndex int IDENTITY(1,1), AnimalTypeId int, Cost decimal(20,2));
CREATE TABLE #TotalAnimalCostAll (thisIndex int IDENTITY(1,1), YearSetupId int, AnimalTypeId int, AnimalType varchar(max), OwnerId int, CustomerId int, AnimalCount int, TtlSpeciesCost decimal(20,2));
CREATE TABLE #CustomerPaymentsAll (thisIndex int IDENTITY(1,1), CustomerID nvarchar(max), TtlPayments decimal(20,2));
CREATE TABLE #CustomerInfoAll (thisIndex int IDENTITY(1,1), OwnerId int, CustomerId int, FName nvarchar(200), LName nvarchar(200),BName nvarchar(200));
CREATE TABLE #ThisReportAll (thisIndex int IDENTITY(1,1), CustomerID nvarchar(max), Year char(4), OverdueBalance decimal(20,2), YearSetupId int);
INSERT INTO #BalanceAdjustmentsAll (CustomerId, Amount)
SELECT CustomerId, SUM(Amount)
FROM BalanceAdjustment
WHERE YearSetupId = 3
GROUP BY CustomerId;
/* GET Costs per Animal for 'This' yearID */
INSERT INTO #AnimalCostsAll (AnimalTypeId, Cost)
SELECT AnimalTypeId, Cost
FROM PerCapitaFee
WHERE YearSetupId = 3;
/* GET animal type totals for owner per year */
INSERT INTO #TotalAnimalCostAll (yearSetupId,AnimalTypeId,AnimalType,OwnerId,CustomerId,AnimalCount,TtlSpeciesCost)
SELECT YearSetup.YearSetupId,AnimalCount.AnimalTypeId,AnimalType.ShortDescription,Owner.OwnerId,Report.CustomerId,AnimalCount.Count,(ac.Cost * AnimalCount.Count)
FROM AnimalCount
INNER JOIN #AnimalCostsAll as ac
ON ac.AnimalTypeId = AnimalCount.AnimalTypeId
INNER JOIN AnimalType
ON AnimalCount.AnimalTypeId=AnimalType.AnimalTypeId
INNER JOIN AnimalLocation
ON AnimalLocation.AnimalLocationid=AnimalCount.AnimalLocationId
INNER JOIN Owner
ON Owner.OwnerId=AnimalLocation.OwnerId
AND Owner.OwnerType = 'P'
INNER JOIN Report
ON Report.ReportId=Owner.ReportId
INNER JOIN YearSetup
ON Report.YearSetupId=YearSetup.YearSetupId
INNER JOIN County
ON County.CountyId=AnimalLocation.CountyId
WHERE YearSetup.YearSetupId = 3 AND Report.Completed IS NOT NULL AND Report.CustomerId IS NOT NULL
/* Get The total payments a customer has made */
INSERT INTO #CustomerPaymentsAll (CustomerID,TtlPayments)
SELECT BPS.CustomerId,SUM(BPS.Amount)
FROM BatchPaymentSplit BPS
LEFT JOIN BatchPayment bp ON BPS.BatchPaymentId=bp.BatchPaymentId
LEFT JOIN Batch b ON bp.BatchId=b.BatchId
WHERE BPS.CustomerId IS NOT NULL
AND
(
((b.BatchTypeId = 'M' OR b.BatchTypeId = 'C' OR b.BatchTypeId = 'E') AND (b.BatchStatusId = 'S'))
OR
((b.BatchTypeId = 'B' OR b.BatchTypeId = 'N' OR b.BatchTypeId = 'R' OR b.BatchTypeId = 'T') AND (b.BatchStatusId = 'S' OR b.BatchStatusId='C'))
)
AND
BPS.YearSetupId = 3
GROUP BY BPS.CustomerId;
/* Deal with the name/id stuff */
INSERT INTO #CustomerInfoAll(FName, LName, BName, OwnerId, CustomerId)
SELECT
o.FirstName AS FName,
o.LastName AS LName,
o.BusinessName AS BName,
o.OwnerId AS OwnerId,
r.CustomerId AS CustomerId
FROM Owner o
INNER JOIN Report r
ON o.ReportId = r.ReportId
AND o.OwnerType = 'P'
WHERE r.CustomerId IN (SELECT CustomerId FROM #TotalAnimalCostAll)
AND r.Completed IS NOT NULL
AND r.YearSetupId = 3
AND NOT EXISTS(
SELECT 1 FROM Report
WHERE r.CustomerId = Report.CustomerId
AND Report.Completed IS NOT NULL
AND r.ReportId != Report.ReportId
AND r.YearSetupId = Report.YearSetupId
AND (
r.Completed < Report.Completed
OR (
r.Completed = Report.Completed
AND r.ReportId < Report.ReportId
)
)
)
ORDER BY CustomerId;
/** MAKE IT SO #1 **************************************************/
/* Simply Joining The Customer Info to the calculated totals to avoid any aggregation shenanigans... */
INSERT INTO #ThisReportAll (CustomerID,Year,OverdueBalance,YearSetupId)
SELECT COALESCE(t.CustomerId,cp.CustomerId,ba.CustomerID), ys.Name AS Year,
CASE
WHEN (SUM(t.TtlSpeciesCost) < 5 AND SUM(t.TtlSpeciesCost) > 0) AND (ys.Name='2015' OR ys.Name='2016')
THEN (5) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
ELSE SUM(t.TtlSpeciesCost) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
END
AS TtlOwnerCost, t.YearSetupId AS YearSetupId
FROM #TotalAnimalCostAll t
FULL OUTER JOIN #CustomerPaymentsAll cp ON t.CustomerId=cp.CustomerID
FULL OUTER JOIN #BalanceAdjustmentsAll ba ON COALESCE(t.CustomerId,cp.CustomerId)=ba.CustomerID
LEFT JOIN YearSetup ys ON COALESCE(t.CustomerId,cp.CustomerId,ba.CustomerID) = ys.YearSetupId
GROUP BY COALESCE(t.CustomerId,cp.CustomerId,ba.CustomerID),ys.Name,cp.TtlPayments, ba.Amount, t.YearSetupId
HAVING
CASE WHEN (SUM(t.TtlSpeciesCost) < 5 AND SUM(t.TtlSpeciesCost) > 0) AND (ys.Name='2015' OR ys.Name='2016')
THEN SUM(5) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
ELSE SUM(t.TtlSpeciesCost) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
END < 0;
/* Return some meaningful report data */
SELECT r.Year AS [YearName],r.CustomerID,left(ci.FName,20) AS [FirstName], left(ci.LName,40) AS [LastName], left(ci.BName,40) AS [BusinessName],r.OverdueBalance AS [Balance],r.YearSetupId
FROM #ThisReportAll r
LEFT JOIN #CustomerInfoAll ci ON r.CustomerID = ci.CustomerId
ORDER BY CAST(r.CustomerID as int) ASC;
DROP TABLE #BalanceAdjustmentsAll;
DROP TABLE #AnimalCostsAll;
DROP TABLE #TotalAnimalCostAll;
DROP TABLE #CustomerPaymentsAll;
DROP TABLE #CustomerInfoAll;
DROP TABLE #ThisReportAll;
Found it. I didn't have a default value for t.TtlSpeciesCost if it was null
SUM(t.TtlSpeciesCost) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
to
SUM(ISNULL(t.TtlSpeciesCost,0)) - Isnull(cp.TtlPayments,0) + Isnull(ba.Amount,0)
Some missing records may be found here:
by adjusting /* Get The total payments a customer has made */
INSERT INTO #CustomerPaymentsAll (CustomerID,TtlPayments)
SELECT BPS.CustomerId,SUM(BPS.Amount)
FROM BatchPaymentSplit BPS
LEFT JOIN BatchPayment bp
ON BPS.BatchPaymentId=bp.BatchPaymentId
LEFT JOIN Batch b
ON bp.BatchId=b.BatchId
AND ((b.BatchTypeId IN ('M', 'C', 'E') AND b.BatchStatusId = 'S')
OR (b.BatchTypeId IN ('B','N','R','T') AND (b.BatchStatusId IN ('S','C')))
WHERE BPS.CustomerId IS NOT NULL
AND BPS.YearSetupId = 3
GROUP BY BPS.CustomerId;
The WHERE on B would have negated the left join causing null records to be omitted. or made the left join to behave like an inner join.
To know for certain we need sample data from your tables showing which records are being omitted that you need to retain.
I also refactored the OR's and made them "IN"s to improve readability.

Error while using same table data twice during inner join

Suppose I have a table, in Database name 'Old', as below:
TABLE A
(
SeniorVehicle varchar(255),
SeniorVehicleAllowance int,
JuniorVehicle varchar(255),
JuniorVehicleAllowance int
ManagerVehicle varchar(255),
ManagerVehicleAllowance int
);
And another table, in Database name 'New' as below:
TABLE B
(
SeniorVehicle int,
SeniorVehicleAllowance int,
JuniorVehicle int,
JuniorVehicleAllowance int,
ManagerVehicle int,
ManagerVehicleAllowance int
);
I want to bring the data from TABLE A of Database 'Old' to TABLE B of Database 'New'.
The thing is that, there is a table named Vehicle in both databases as bellow:
TABLE Vehicle
(
VehicleID int pk,
VehicleName varchar(255)
)
Values in SeniorVehicle, JuniorVehicle and ManagerVehicle columns in TABLE A are the VehicleName value in TABLE Vehicle. But the value of SeniorVehicle, JuniorVehicle and ManagerVehicle that must be stored in TABLE B must be the value of VehicleID column in the Vehicle Table.
How to achieve this without error????
I have tried the following:
INSERT INTO B
(SeniorVehicle, SeniorVehicleAllowance, JuniorVehicle, JuniorniorVehicleAllowance, ManagerVehicle, ManagerVehicleAllowance)
SELECT Vehicle.VehicleID, c.SeniorVehicleAllowance, c.VehicleID, c.JuniorVehicleAllowance, c.VehicleID, c.ManagerVehicleAllowance
FROM (SELECT b.SeniorVehicle, b.SeniorVehicleAllowance, Vehicle.VehicleID, b.JuniorVehicleAllowance, b.VehicleID, b.ManagerVehicleAllowance
FROM (SELECT a.SeniorVehicle, a.SeniorVehicleAllowance, a.JuniorVehicle, a.JuniorVehicleAllowance, Vehicle.VehicleID, a.ManagerVehicleAllowance
FROM (SELECT SeniorVehicle, SeniorVehicleAllowance, JuniorVehicle, JuniorVehicleAllowance, ManagerVehicle, ManagerVehicleAllowance FROM A) as a
Inner join
Vehicle
ON a.ManagerVehicle = Vehicle.VehicleName) as b
Inner join
Vehicle
ON b.JuniorVehicle = Vehicle.VehicleName) as c
Inner join
Vehicle
ON c.SeniorVehicle = Vehicle.VehicleName
I get the following error:
The column 'VehicleID' was specified multiple times for 'c'
My Databse is MSSQL Server 2008 R2
Reformatting your current query gives:
SELECT
Vehicle.VehicleID,
c.SeniorVehicleAllowance,
c.VehicleID,
c.JuniorVehicleAllowance,
c.VehicleID,
c.ManagerVehicleAllowance
FROM (
SELECT b.SeniorVehicle,
b.SeniorVehicleAllowance,
Vehicle.VehicleID,
b.JuniorVehicleAllowance,
b.VehicleID,
b.ManagerVehicleAllowance
FROM (
SELECT a.SeniorVehicle,
a.SeniorVehicleAllowance,
a.JuniorVehicle,
a.JuniorVehicleAllowance,
Vehicle.VehicleID,
a.ManagerVehicleAllowance
FROM (
SELECT SeniorVehicle,
SeniorVehicleAllowance,
JuniorVehicle,
JuniorVehicleAllowance,
ManagerVehicle,
ManagerVehicleAllowance
FROM A
) as a
Inner join Vehicle
ON a.ManagerVehicle = Vehicle.VehicleName
) as b
Inner join Vehicle
ON b.JuniorVehicle = Vehicle.VehicleName
) as c
Inner join Vehicle
ON c.SeniorVehicle = Vehicle.VehicleName
In this query, the sub query aliased c has two columns called VehicleID (which is what your error message is telling you.
The smallest change to fix the issue is to alias the columns in the sub query, e.g:
SELECT
Vehicle.VehicleID AS SeniorVehicleId,
c.SeniorVehicleAllowance,
c.JuniorVehicleId,
c.JuniorVehicleAllowance,
c.ManagerVehicleID,
c.ManagerVehicleAllowance
FROM (
SELECT b.SeniorVehicle,
b.SeniorVehicleAllowance,
Vehicle.VehicleID AS JuniorVehicleId,
b.JuniorVehicleAllowance,
b.ManagerVehicleID,
b.ManagerVehicleAllowance
FROM (
SELECT a.SeniorVehicle,
a.SeniorVehicleAllowance,
a.JuniorVehicle,
a.JuniorVehicleAllowance,
Vehicle.VehicleID AS ManagerVehicleID,
a.ManagerVehicleAllowance
-- Rest ommited for brevity
It would be also possible to re-write the query with more joins, and omit the need for the subqueries altogether also:
SELECT srmgr.VehicleId AS SeniorVehicleId,
A.SeniorVehicleAllowance,
jrmgr.VehicleId AS JuniorVehicleId,
A.JuniorVehicleAllowance,
mgr.VehicleId AS ManagerVehicleId,
A.ManagerVehicleAllowance
FROM A
INNER JOIN Vehicle AS mgr
ON a.ManagerVehicle = mgr.VehicleName
INNER JOIN Vehicle AS jrmgr
ON a.ManagerVehicle = jrmgr.VehicleName
INNER JOIN Vehicle AS srmgr
ON a.ManagerVehicle = srmgr.VehicleName

sql query - update fields in existing with record values in the same table

Environment: SQL Server 2012
I have a transaction table that contains a group of records with group id column.
In the example illustrated below, group 2 records were copied from group 1 records, Except for the sideId, sideSort, topId and topSort columns. Is there a way to cascade that down from group 1 to group 2 for just topSort and sideSort? The hard part is that topId and sideId aren't the same because of Identity fields in parent tables.
Here is a sqlfiddle of the example
You can do it this way. This is based on the assumption that you copy all the records for one group (#copiedFromGroupId) to another (#copiedToGroupId), i.e. that the ID's will be shifted by the number of records in the first group.
declare #copiedFromGroupId int = 1
declare #copiedToGroupId int = 2
declare #shift int
select #shift = (select max(id) from Tracker where GroupId = #copiedToGroupId)
- (select max(id) from Tracker where GroupId = #copiedFromGroupId)
UPDATE T1
SET
T1.TopSort = T2.TopSort,
T1.SideSort = T2.SideSort
FROM Tracker T1
INNER JOIN Tracker T2 ON T1.ID = T2.ID + #shift
Check this SQL Fiddle
This is based on the row_number over the ORDER of TopId and SortID columns:
update test
set test.topSort = mix.topSort, test.sideSort = mix.sideSort
from
(select a.groupid aGroupid, b.groupID, b.Id bID, a.topSort, a.sideSort
from (select groupid,
row_number() over(order by topID, sideId) rn,
topSort, sideSort,
id
from test where groupid=1) a
inner join
(select groupid,
row_number() over(order by topID, sideId) rn,
topSort, sideSort,
id
from test where groupid=2) b ON a.rn = b.rn) mix
inner join test on test.id=mix.bId
WHERE test.groupid=2;
SQLFiddle
Assuming that Id is an order field in the Group:
WITH C as
(
select Tracker.*,
ROW_NUMBER() OVER (PARTITION BY GroupId ORDER BY Id) as RN
FROM Tracker
)
UPDATE CT
SET CT.topSort=CTU.topSort,
CT.sideSort=CTU.sideSort
FROM C as CT
JOIN C as CTU ON (CT.rn=CTU.rn)
and (CTU.GroupID=1)
WHERE CT.GroupID=2
SQLFiddle demo