Select only columns from joined tables from CTE - sql-server

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

Related

SQL Server 2005 Select Data From Table1 and Table2 but if Table2 column1 value is null Select Data From Table3

My Query IS
SELECT TblPharmacyBillingDetails.UPBNo, TblMasterBillingData.IPDNo, InPatRegistration.PatTitle+PatientName, TblPharmacyBillingDetails.InvoiceNo, TblPharmacyBillingDetails.InvoiceDateTime, TblPharmacyBillingDetails.BillingAmount
FROM TblPharmacyBillingDetails
INNER JOIN TblMasterBillingData ON TblPharmacyBillingDetails.UPBNo = TblMasterBillingData.UPBNo
INNER JOIN InPatRegistration ON TblMasterBillingData.IPDNo = InPatRegistration.IPDNo
but if TblMasterBillingData.IPDNo value is NULL select Data From TblMasterBillingData.OPDNo and
INNER JOIN OutPatRegistration ON TblMasterBillingData.OPDNo = OutPatRegistration.IPDNo
Method #1: Using UNION
SELECT * FROm
(
SELECT TblPharmacyBillingDetails.UPBNo,
TblMasterBillingData.IPDNo,
InPatRegistration.PatTitle+PatientName,
TblPharmacyBillingDetails.InvoiceNo,
TblPharmacyBillingDetails.InvoiceDateTime,
TblPharmacyBillingDetails.BillingAmount
FROM TblPharmacyBillingDetails
INNER JOIN TblMasterBillingData ON TblPharmacyBillingDetails.UPBNo = TblMasterBillingData.UPBNo
INNER JOIN InPatRegistration ON TblMasterBillingData.IPDNo = InPatRegistration.IPDNo
WHERE TblMasterBillingData.IPDNo IS NOT NULL
UNION ALL
SELECT TblPharmacyBillingDetails.UPBNo,
TblMasterBillingData.OPDNo,
OutPatRegistration .PatTitle + PatientName,
TblPharmacyBillingDetails.InvoiceNo,
TblPharmacyBillingDetails.InvoiceDateTime,
TblPharmacyBillingDetails.BillingAmount
FROM TblPharmacyBillingDetails
INNER JOIN TblMasterBillingData ON TblPharmacyBillingDetails.UPBNo = TblMasterBillingData.UPBNo
INNER JOIN OutPatRegistration ON TblMasterBillingData.OPDNo = OutPatRegistration.OPDNo
WHERE TblMasterBillingData.OPDNo IS NOT NULL
)Tmp
ORDER BY TblPharmacyBillingDetails.UPBNo
Method #2 Using ISNULL and LEFT JOIN
SELECT TblPharmacyBillingDetails.UPBNo,
ISNULL(TblMasterBillingData.IPDNo,TblMasterBillingData.OPDNo),
ISNULL(IP.PatTitle + IP.PatientName, OP.PatTitle + OP.PatientName),
TblPharmacyBillingDetails.InvoiceNo,
TblPharmacyBillingDetails.InvoiceDateTime,
TblPharmacyBillingDetails.BillingAmount
FROM TblPharmacyBillingDetails
INNER JOIN TblMasterBillingData ON TblPharmacyBillingDetails.UPBNo = TblMasterBillingData.UPBNo
LEFT JOIN InPatRegistration IP ON TblMasterBillingData.IPDNo = IP.IPDNo
LEFT JOIN outPatRegistration OP ON TblMasterBillingData.OPDNo = OP.OPDNo
ORDER BY TblPharmacyBillingDetails.UPBNo
You can write either case statement or ISNULL() function as shown below in the demo query.
SELECT
Orders.OrderID,
Case when Customers1.CustomerName is null then Customers2.CustomerName else Customers1.CustomerName
end as CustomerName, --way 1
ISNULL(Customers1.CustomerName, Customers2.CustomerName) as Customer, --way 2
Orders.OrderDate
FROM Orders
INNER JOIN Customers1 ON Orders.CustomerID = Customers1.CustomerID
INNER JOIN Customers2 ON Orders.CustomerID = Customers2.CustomerID
-- where your condition here
-- order by your column name
You can also check whether data is available or not in the table and join the table accordingly using if exists as shown below.
if exists(select 1 from tablename where columnname = <your values>)

SQL Server : compare two CTE Tables

I would like to compare two CTES tables. The purpose of this is that i would like to see which PersonKey(PK) exists in another CTE table i have created. So i could match the data after.
WITH cte1 AS
(
SELECT DISTINCT 1.PERSON_CODE,la.AIM
FROM [PEOPLE_UNITS] 1
INNER JOIN PEOPLE p ON p.PERSON_CODE = 1.PERSON_CODE
INNER JOIN AIMS la on la.person_code = 1.PERSON_CODE
WHERE la.AIM = 'Delta'
),
cte2 AS
(
SELECT p.PERSON_CODE,FES_UINS_INSTANCE_CODE
FROM [ebslive].[dbo].[PEOPLE_UNITS] 1
INNER JOIN dbo.PEOPLE p ON p.PERSON_CODE = 1.PERSON_CODE
INNER JOIN dbo.PEOPLE_UIO PUIO ON 1.UIO_ID = puio.UIO_ID
INNER JOIN dbo.LEARNER_AIMS la on la.person_code = 1.PERSON_CODE
INNER JOIN dbo.UNIT_INSTANCE_OCCURRENCES UIO ON UIO.UIO_ID = la.UIO_ID
INNER JOIN dbo.UNIT_INSTANCES UI ON UI.FES_UNIT_INSTANCE_CODE = uio.FES_UINS_INSTANCE_CODE
)
THis will do it:
Select PERSON_CODE from cte a where exists
(
select 1 from cte2 b where a.PERSON_CODE = b.PERSON_CODE
)

alternative to sub query in join

I have a SQL query that I'm trying to optimize.
Is there a better way to avoid using subquery here?
Got a suggestion on using Row_number(),
posting this with some corrections
DECLARE #curdate DATETIME
SET #curdate = GETDATE()
SELECT DISTINCT
SIS.StudentID, StudentCoverage.StudentCoverageDataID,
Student.FirstName, Student.LastName,
Student.DateOfBirth, Student.Gender,
ASMT.AssessmentDate
FROM
SIS (NOLOCK)
INNER JOIN
SISMaster (NOLOCK) ON SISMaster.SISID = SIS.SISID
INNER JOIN
Assessment ASMT ON SIS.StudentID = ASMT.StudentId
INNER JOIN
StudentCoverage (NOLOCK) ON StudentCoverage.StudentID = SIS.StudentID
INNER JOIN
Organization (NOLOCK) ON StudentCoverage.OrgID = Organization.OrganizationID
INNER JOIN
Student (NOLOCK) ON Student.StudentID = SIS.StudentID
INNER JOIN
StudentCoverageData (NOLOCK) ON StudentCoverageData.StudentCoverageID = StudentCoverage.StudentCoverageID
AND StudentCoverageData.StudentCoverageDataID = (SELECT TOP 1 StudentCoverageData.StudentCoverageDataID
FROM StudentCoverage
INNER JOIN StudentCoverageData ON StudentCoverageData.StudentCoverageID = StudentCoverage.StudentCoverageID
WHERE StudentCoverage.StudentId = SIS.StudentID
AND StudentCoverageData.Active = 1
AND StudentCoverageData.EffectiveDate <= #curdate
AND (StudentCoverageData.ExitDate IS NULL OR StudentCoverageData.ExitDate > #curdate)
ORDER BY StudentCoverageData.AsOfDate DESC)
All Tables in your subquery is exists in inner join clause, so you could rewrite your query like this:
;WITH temps AS
(
DECLARE #curdate DATETIME = GETDATE()
SELECT
SIS.StudentID, StudentCoverage.StudentCoverageDataID,
Student.FirstName, Student.LastName,
Student.DateOfBirth, Student.Gender,
ASMT.AssessmentDate,
ROW_NUMBER() OVER (PARTITION BY StudentCoverageData.StudentCoverageDataID ORDER BY StudentCoverageData.AsOfDate) AS RowIndex
FROM
SIS (NOLOCK)
INNER JOIN
SISMaster (NOLOCK) ON SISMaster.SISID = SIS.SISID
INNER JOIN
StudentCoverage (NOLOCK) ON StudentCoverage.StudentID = SIS.StudentID
INNER JOIN
Organization (NOLOCK) ON StudentCoverage.OrgID = Organization.OrganizationID
INNER JOIN
Student (NOLOCK) ON Student.StudentID = SIS.StudentID
INNER JOIN
StudentCoverageData (NOLOCK) ON StudentCoverageData.StudentCoverageID = StudentCoverage.StudentCoverageID
WHERE StudentCoverageData.Active = 1
AND StudentCoverageData.EffectiveDate <= #curdate
AND (StudentCoverageData.ExitDate IS NULL OR StudentCoverageData.ExitDate > #curdate)
)
SELECT * FROM temps t
WHERE t.RowIndex = 1

Is it possible to Replace CTE and SELECT with just single sql query (dependent results)

I have the following query. Given productid as input (2,4,5) i want to get keyid associate with that list. Then i want to get all products associated with that keyids.
For example:
suppose i am passing productid as 2,4,5 as input to my sproc, i will get keyids as 22,34,35,38 (CTE result). This keys are mapped to the input productlist. Based on this keys (CTE result) i want all the products associated to this keys. Say the keyid = 22 will now have product names with product id as 2,4,5,89 & keyid = 34 will now have products associated to 2,4,5,23,45 etc.
I came up with the following solution for the above problem. I am just hoping whether we could somehow improve this solution or do this job in single query as two tables are getting repeated.
WITH GetKey_CTE
AS
(
SELECT k.id, some other select statements
FROM KeyDim k
INNER JOIN KeyData kd on kd.id = k.id
INNER JOIN KeyProductMapping kpm on kpm.id = k.id and kpm.mkey = k.mkey
INNER JOIN Products p on p.productid = kpm.productid
and p.productid IN (2,4,5)
LEFT JOIN some more joins
WHERE clause conditions
)
SELECT cte.id as keyid, pn.productname, some other columns
FROM GetKey_CTE cte
INNER JOIN KeyProductMapping kpm on cte.id = kpm.id
INNER JOIN Products pn on pn.productid = kpm.productid
ORDER BY cte.id
Dataset Example for products and productkeymapping tables :
For Products table:
productid name
1 car
2 bike
3 plane
4 bus
5 train
45 cycle
ProductKeyMapping table
productid keyid
1 23
2 987
45 23
1 56
say input productid is 1, then final result should be:
keyid productid name
23 1 car
23 45 cycle
56 1 car
just looking at the data and that simple example
select pm2.*, product.name
from productmapping pm1
join productmapping pm2
on pm2.keyid = pm1.keyid
and pm1.productid in (1)
join product
on product.id = pm2.productid
declare #product table(id int, name varchar(20));
declare #map table(productid int, keyid int);
insert into #product values
(1, 'car'),
(2, 'bike'),
(3, 'plane'),
(4, 'bus'),
(5, 'train'),
(45, 'cycle');
insert into #map values
(1, '23'),
(2, '987'),
(45, '23'),
(1, '56');
select pm2.*, p.name
from #map pm1
join #map pm2
on pm2.keyid = pm1.keyid
and pm1.productid in (1)
join #product p
on p.id = pm2.productid
order by pm2.keyid;
you can also done by using sub query
SELECT * FROM KeyProductMapping km
INNER JOIN
(
SELECT k.id, some other select statements
FROM KeyDim k
INNER JOIN KeyData kd ON kd.id = k.id
INNER JOIN KeyProductMapping kpm ON kpm.id = k.id AND kpm.mkey = k.mkey
INNER JOIN Products p ON p.productid = kpm.productid
AND p.productid IN (2,4,5)
LEFT JOIN some more joins
WHERE clause conditions) AS p ON p.id = km.id
INNER JOIN Products pn ON p.productid = km.productid
ORDER BY cte.id
SELECT cte.id as keyid, pn.productname, some other columns
FROM ( SELECT k.id, some other select statements
FROM KeyDim k
JOIN KeyData kd
on kd.id = k.id
JOIN KeyProductMapping kpm
on kpm.id = k.id
and kpm.mkey = k.mkey
JOIN Products p
on p.productid = kpm.productid
and p.productid IN (2,4,5)
LEFT JOIN some more joins
WHERE clause conditions
) CTE
JOIN KeyProductMapping kpm
on cte.id = kpm.id
JOIN Products pn
on pn.productid = kpm.productid
ORDER BY cte.id
Above you you query with the CTE in line (a subquery)
A lot of stuff does not make sense to me
JOIN KeyProductMapping kpm
on kpm.id = k.id
and kpm.mkey = k.mkey
JOIN Products p
on p.productid = kpm.productid
and p.productid IN (2,4,5)
is the same as
JOIN KeyProductMapping kpm
on kpm.id = k.id
and kpm.mkey = k.mkey
and p.productid IN (2,4,5)
unless product does not have those values
why
SELECT k.id, some other select statements
FROM KeyDim k
JOIN KeyData kd
on kd.id = k.id
same as
SELECT kd.id -- move this to main select, some other select statements
FROM KeyData kd
why?
LEFT JOIN some more joins
move that to main statement
You can replace the CTE with an inline view like below but note sure why you are duplicating the JOINS again. Can you post some sample data along with your desired result to look further.
SELECT cte.id AS keyid, pn.productname, some other columns
FROM (
SELECT k.id, some other select statements
FROM KeyDim k
INNER JOIN KeyData kd ON kd.id = k.id
INNER JOIN KeyProductMapping kpm ON kpm.id = k.id AND kpm.mkey = k.mkey
INNER JOIN Products p ON p.productid = kpm.productid
AND p.productid IN (2,4,5)
LEFT JOIN some more joins
WHERE clause conditions ) cte
INNER JOIN KeyProductMapping kpm ON cte.id = kpm.id
INNER JOIN Products pn ON cte.productid = kpm.productid
ORDER BY cte.id

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)

Resources