SQL Query joining parent table with several children rows into one row - sql-server

I'm trying to implement query to take setups information from database where one setup has link to several items types: Controller, platform and KVM device.
This way:
Rack
|
Setup
/ | \
controller Platform KVM
Connections between parent and children are stored in another table.
I tried the bellow query, but I got setup children in separated rows.
How can I improve query to solve this?
Query:
select R.Id as Rack_Id,
S.Id,C.Id as Setup_Id,
P.Id as Platform_Id,
K.Id as KVM_Id,
R.Capacity, R.[Rack location],
S.[Location in Rack], C.[Controller IP], P.ISMP, P.Platform
From #Racks R join LinksAre LR on LR.SourceId = R.Id
join #Setups S on LR.TargetId=S.Id
left join LinksAre LS on LS.SourceId = S.Id
left join #KVMs K on LS.TargetID = K.Id
left join #Controllers C on LS.TargetId=C.Id
left join #Platforms P on LS.TargetId = P.Id
order by R.Id, S.Id
Thanks!

Think you might need a subquery:
select R.Id as Rack_Id,
S.Id,C.Id as Setup_Id,
P.Id as Platform_Id,
K.Id as KVM_Id,
R.Capacity, R.[Rack location],
( SELECT S.[Location in Rack] FROM #Setups S
WHERE S.ID = LR.TargetId) AS ColumnA,
C.[Controller IP],
P.ISMP, P.Platform
From #Racks R join LinksAre LR on LR.SourceId = R.Id
left join LinksAre LS on LS.SourceId = S.Id
left join #KVMs K on LS.TargetID = K.Id
left join #Controllers C on LS.TargetId=C.Id
left join #Platforms P on LS.TargetId = P.Id
order by R.Id, S.Id

Related

SQL to find which table has diag_code filled, and then look it up in lookup_table

I have a query and a diag_code is either in one table (UM_SERVICE) or the other (LOS), but I can't join both tables to get diag_code that isn't null, that I can think of. Does this look ok for finding if diag_code is in one of the tables and lookup table? It's possible to have both LOS and UM_SERVICE have a diag code on different rows, and they could be different, and both or one could be in the lookup table. I'm not seeing anything in internet search.
Here's a simplified stored procedure:
SELECT distinct
c.id
,uc.id
,c.person_id
FROM dbo.CASES c
INNER JOIN dbo.UM_CASE uc with (NOLOCK) ON uc.case_id = c.id
LEFT JOIN dbo.UM_SERVICE sv (NOLOCK) ON sv.case_id = omc.case_id
LEFT JOIN dbo.UM_SERVICE_CERT usc on usc.service_id = sv.id
LEFT JOIN dbo.LOS S WITH (NOLOCK) ON S.case_id = UC.case_id
LEFT JOIN dbo.LOS_EXTENSION SC WITH (NOLOCK) ON SC.los_id = S.id
INNER JOIN dbo.PERSON op with (NOLOCK) on op.id = c.Person_id
WHERE
(sv.diag_code is not null and c.case_id = sv.case_id
or
s.diag_code is not null and c.case_id = s.case_id)
and
(sv.diag_code is not null and sv.diag_code in (select diag_code from TABLE_LOOKUP)
or
s.diag_code is not null and s.diag_code in (select diag_code from TABLE_LOOKUP)
Table setups like this:
CASES
id person_id
UM_CASE
case_id
LOS
case_id id
LOS_EXTENSION
los_id
Person
id cid
UM_SERVICE
case_id diag_code
UM_SERVICE_CERT
service_id id
TABLE_LOOKUP
diag_code
Since you have two different searches being run, it is going to be much easier to write/read by writing the searches individually and then bringing your two results sets together using the UNION operator. The UNION will eliminate duplicates across the two result sets in a similar manner to what your usage of SELECT DISTINCT is doing for a single result set.
Like so:
/*first part of union performs seach using filter on dbo.UM_SERVICE*/
SELECT
c.id
,uc.id
,c.person_id
FROM
dbo.CASES AS c
INNER JOIN dbo.UM_CASE AS uc ON uc.case_id=c.id
LEFT JOIN dbo.UM_SERVICE AS sv ON sv.case_id = omc.case_id
LEFT JOIN dbo.UM_SERVICE_CERT AS usc on usc.service_id=sv.id
LEFT JOIN dbo.LOS AS S ON S.case_id = UC.case_id
LEFT JOIN dbo.LOS_EXTENSION AS SC ON SC.los_id= S.id
INNER JOIN dbo.PERSON AS op on op.id=c.Person_id
WHERE
sv.diag_code in (select diag_code from TABLE_LOOKUP) /*will eliminate null values in sv.diag_code*/
UNION /*deduplicate result sets*/
/*second part of union performs search using filter on dbo.LOS*/
SELECT
c.id
,uc.id
,c.person_id
FROM
dbo.CASES AS c
INNER JOIN dbo.UM_CASE AS uc ON uc.case_id=c.id
LEFT JOIN dbo.UM_SERVICE AS sv ON sv.case_id = omc.case_id
LEFT JOIN dbo.UM_SERVICE_CERT AS usc on usc.service_id=sv.id
LEFT JOIN dbo.LOS AS S ON S.case_id = UC.case_id
LEFT JOIN dbo.LOS_EXTENSION AS SC ON SC.los_id= S.id
INNER JOIN dbo.PERSON AS op on op.id=c.Person_id
WHERE
s.diag_code in (select diag_code from TABLE_LOOKUP); /*will eliminate null values in s.diag_code*/

How to insert keys from one database to another?

Here is my code for inserting values from AdventureWorks to custom database.
I needed to transfer identifiers from AdventureWorks too but copy of identifiers are not allowed. So I thought using distinct with identifier would be enough, but I still get error about inserting duplicates.
If you could comment and tell me what I am doing wrong I would be very grateful.
Thank you!
Here is my full attempt: https://pastebin.com/ZPniteh1
set identity_insert proizvodi ON
insert into proizvodi (ProizvodID, Sifra, Naziv, Kategorija, Podkategorija, Boja, Cijena, StanjeZaliha)
select distinct
p.ProductID, p.ProductNumber,p.[Name], pc.[Name],psc.[Name],
p.Color, p.ListPrice, pii.Quantity
from
AdventureWorks2017.Production.Product as p
join
AdventureWorks2017.Production.ProductSubcategory as psc on psc.ProductSubcategoryID = p.ProductSubcategoryID
join
AdventureWorks2017.Production.ProductCategory as pc on pc.ProductCategoryID = psc.ProductCategoryID
inner join
AdventureWorks2017.Production.ProductInventory as pii on pii.ProductID = p.ProductID
inner join
AdventureWorks2017.Sales.SalesOrderDetail as sod on sod.ProductID = p.ProductID
inner join
AdventureWorks2017.Sales.SalesOrderHeader as soh on soh.SalesOrderID = sod.SalesOrderID
inner join
AdventureWorks2017.Sales.SalesTerritory as st on st.TerritoryID = soh.TerritoryID
inner join
AdventureWorks2017.Production.[Location] as l on l.LocationID = pii.LocationID
where
st.[Group] ='Europe'
order by
p.ProductID
set identity_insert proizvodi OFF

TSQL: SUM not working like i thought it would

I have the following query:
SELECT
a.Name,
ISNULL(CAST(sum((b.qty * b.unit_rate)* b.Eng_RPQ )/100 AS DECIMAL(8,1)),0) AS [EngHours],
SUM(BR.BlendedRate)
FROM
Activity_Details b
INNER JOIN
Activity c on b.activity_id = c.id
INNER JOIN
Project p on p.id = c.project_id
RIGHT OUTER JOIN
Discipline a on c.discipline_id = a.id
INNER JOIN
(SELECT
a.Name, c.id,
CAST(f.POH * (d.HourlyRate * (1-(r.Discount/100))/100) AS DECIMAL(8,2)) AS BlendedRate
FROM
Activity_Details b
INNER JOIN
Activity c on b.activity_id = c.id
INNER JOIN
Team f on f.activity_id = c.id
INNER JOIN
SOF_Details d on d.id = f.sof_detail_id
INNER JOIN
Project p on p.id = c.project_id
INNER JOIN
Rate r on r.projectid = p.id
INNER JOIN
Teammate_Type tt on tt.id = f.team_type_id
RIGHT OUTER JOIN
Discipline a on c.discipline_id = a.id
GROUP BY
a.Name, c.id, f.POH, d.HourlyRate, r.Discount) AS BR ON BR.id = c.id
GROUP BY
a.Name
ORDER BY
a.Name
Which yields:
Name EngHours BlendedRate
Architechtural 80.8 38.48
Architechtural 80.8 55.33
Architechtural 80.8 55.40
I want to SUM this BlendedRate and ROUND it but if i try SUM(BR.BlendedRate) to the SELECT and remove the BR.BlendedRate in the GROUP BY
I get:
Name EngHours BlendedRate
Architechtural 242.3 895.26
I was expecting BlendedRate to equal 149.21
Any idea what i am doing wrong?
unable to comment due to reputation. It is a crude solution, but your code is returning duplicated (seemingly 6) records. The code should be fixed elsewhere, but without sample data it is difficult. In the mean time a crude solution would be to add a distinct clause to the sum function
SUM( DISTINCT BR.BlendedRate)

Select only columns from joined tables from CTE

The following is my CTE:
;WITH CTE AS
(SELECT O.*, E.Num, E.Amount
FROM OData O
INNER JOIN Equip E
ON O.Name = E.Name)
SELECT * FROM CTE -- gives results I want to join to
The following is the query that I want to SELECT from (and only use this SELECT statement for my query results:
SELECT
MU.Type
,MU.Num
,MU.MTBUR
,MF.MTBF
,MU.Hours
,MF.Hours
FROM
MUType_Stage MU
INNER JOIN
MFType_Stage MF
ON
MU.Type = MF.Type
AND
MU.Num = MF.Num
-- Need do JOIN to CTE right here
INNER JOIN
Status_STAGE S
ON
MU.Nu = S.Part
LEFT OUTER JOIN
RCN N
ON
N.Name = R.Part
LEFT OUTER JOIN
Repair RR
ON
R.ACSS_Name = RR.Name
So basically I need to JOIN to the CTE inside the SELECT query in which I want the results.
OR ALTERNATIVELY Uses this select statement to join to the CTE but only what the selected columns from the second select statement
Try this syntax
WITH CTE
AS (SELECT O.*,
E.Num,
E.Amount
FROM OData O
INNER JOIN Equip E
ON O.Name = E.Name)
SELECT MU.Type,
MU.Num,
MU.MTBUR,
MF.MTBF,
MU.Hours,
MF.Hours
FROM MUType_Stage MU
INNER JOIN MFByACType_Stage MF
ON MU.Type = MF.Type
AND MU.Num = MF.Num
INNER JOIN CTE C --- JOIN HERE as like other tables
ON C.Num = MF.Num
INNER JOIN Status_STAGE S
ON MU.Nu = S.Part
LEFT OUTER JOIN RCN N
ON N.Name = R.Part
LEFT OUTER JOIN Repair RR
ON R.ACSS_Name = RR.Name

SQL Server Nested Query Performance

I need some help writing this query for SQL Server. The nested part makes this query take almost a minute to run on 27,000 records. I think it needs a temp table, but I have not done this before. Can someone give me an idea how I might do this?
SELECT
r.ID,
r.CloseDate,
r.RepairOrderStatus 'Repair Status',
p.PartNumber ModInPN,
p.PartDescription ModInDesc,
pr.RMANumber,
c.FullName OpsTech,
(SELECT COUNT (*)
FROM dbo.TestPartsReplaced tpr
WHERE tpr.RepairID = r.ID) Qty
FROM dbo.RepairTicket r LEFT JOIN dbo.Parts p ON r.ModuleInPartID = p.ID
LEFT JOIN dbo.PartReturn pr ON r.PartReturnID = pr.ID
LEFT JOIN dbo.Contact c ON c.ID = r.ContactTechID
Try this....
SELECT
r.ID,
r.CloseDate,
r.RepairOrderStatus 'Repair Status',
p.PartNumber ModInPN,
p.PartDescription ModInDesc,
pr.RMANumber,
c.FullName OpsTech,
Qty.[Count] AS Quantity
FROM dbo.RepairTicket r LEFT JOIN dbo.Parts p ON r.ModuleInPartID = p.ID
LEFT JOIN dbo.PartReturn pr ON r.PartReturnID = pr.ID
LEFT JOIN dbo.Contact c ON c.ID = r.ContactTechID
LEFT JOIN (SELECT RepairID , COUNT (*) AS [Count]
FROM dbo.TestPartsReplaced
GROUP BY RepairID) Qty ON Qty.RepairID = r.ID

Resources