How to merge these queries into 1 using subquery - sql

Select * from HotelPerson
Where RoomID IN (select ID from HotelRoom Where BookingID = 36 )
Select * from HotelCancelationPolicy
Where RoomID IN (select ID from HotelRoom Where BookingID = 36 )
How can I merge these both queries into 1 query ?

This will give you all the columns from both tables in one table.
SELECT *
FROM HotelPerson A, HotelCancelationPolicy B
WHERE A.RoomID = B.RoomID
AND A.RoomID IN (SELECT ID FROM HotelRoom WHERE BookingID = 36)

Use UNION to Get Distinct elements or UNION ALL for all rows from both tables
Select * from HotelPerson
Where RoomID IN (select ID from HotelRoom Where BookingID = 36 )
UNION ALL
Select * from HotelCancelationPolicy
Where RoomID IN (select ID from HotelRoom Where BookingID = 36 )

I guess you want to join the two tables:
select *
from HotelPerson hp
inner join HotelCancelationPolicy hcp
on hp.RoomId = hcp.RoomId
where hp.RoomID IN (select ID
from HotelRoom
where BookingID = 36 )

Related

Many to Many with multiple Ands

I am trying a simple (or not) query to get Users that exist in 2 Departments.
Struct:
User
ID
Name
UserDepartment
ID
IDUser
IDDepartment
Department
ID
Name
So i want users from DepartmentA and DepartmentB (
Is imposible to do:
Select * from User as US
left join UserDepartment as DP on User.ID = UserDepartment.IDUser
where DP.IDDepartment = 1 and DP.IDDepartment = 2
Zero results...
An query to resolve this is sothing like:
select * from UserDepartment
where IDDepartment in (1,2)
group by IDUser
having COUNT(*)=2
But is this the only solution? there are other easy queries out there?
To get all users that belong in both 1 and 2 departments:
SELECT *
FROM User
WHERE User.ID IN (SELECT UserID FROM UserDepartment WHERE IDDepartment = 1)
AND User.ID IN (SELECT UserID FROM UserDepartment WHERE IDDepartment = 2)
The results are essentially the same as the latter query you have, except it specifically looks for people who are in both "1" and "2", rather than anybody who has 2 or more department records that belong to "1" or "2" (doesn't include people with two "1" records but no "2" records).
If there's information from the userdepartment table you want included in the results, just change it to:
SELECT *
FROM User US
INNER JOIN (SELECT * FROM UserDepartment WHERE IDDepartment IN(1,2)) DP ON US.ID = DP.UserID
WHERE User.ID IN (SELECT UserID FROM UserDepartment WHERE IDDepartment = 1)
AND User.ID IN (SELECT UserID FROM UserDepartment WHERE IDDepartment = 2)
This seems like a job for INTERSECT. You can get the list of user id's you want by doing something like:
SELECT IDUser FROM UserDepartment WHERE IDDepartment = 1
INTERSECT
SELECT IDUser FROM UserDepartment WHERE IDDepartment = 2
/*** If only users for dept 1 and 2 need to be shown the use this query ****/
Select * from #User u
inner join
(
Select d1.UserID from #UserDepartment d1
where d1.Department = 1
intersect
Select d2.UserID from #UserDepartment d2
where d2.Department = 2
except
Select d2.UserID from #UserDepartment d2
where d2.Department not in (1,2)
)t on u.ID = t.UserID
/***If the users that belong to dept 1 and 2 and can exist in
other depts then use this one**/
Select * from #User u
inner join
(
Select d1.UserID from #UserDepartment d1
where d1.Department = 1
intersect
Select d2.UserID from #UserDepartment d2
where d2.Department = 2
)t on u.ID = t.UserID
/**To test use the following commented code**/
/*Select * into #User from
(
Select 1 as ID, 'A' as Name
union
Select 2,'B'
union
Select 3,'C'
union
Select 4,'D'
union
Select 5,'E'
union
Select 6,'F'
union
Select 7,'G'
union
Select 8,'H'
union
Select 9,'I'
union
Select 10,'G'
)t
Select * into #Department from
(
Select 1 as ID, 'D1' as Name
union
Select 2,'D2'
union
Select 3,'D3'
union
Select 4,'D4'
)t2
Select * into #UserDepartment from
(
Select 1 AS ID ,1 AS UserID ,1 AS Department
union
Select 2,1,2
union
Select 3,1,3
union
Select 4,2,1
union
Select 5,3,2
union
Select 6,4,1
union
Select 7,4,2
)t3
*/

Select max date rows for unique key

I have a select statement.
SELECT x.ndc_id
,z.attr_val AS trade_name
,x.quote_price
,x.eff_dt FROM contract_ndc_brg x
LEFT JOIN ndc_attr AS z ON z.field_id = 150
where contract_num_val = (
SELECT item_name
FROM [contract]
WHERE item_id = 184
)
Notice there are two rows with the same ndc_id. I want these results but only one result for each ndc_id which has the highest eff_dt.
I tried adding to the where clause:
SELECT x.ndc_id
,z.attr_val AS trade_name
,x.quote_price
,x.eff_dt FROM contract_ndc_brg x
LEFT JOIN ndc_attr AS z ON z.field_id = 150
where contract_num_val = (
SELECT item_name
FROM [contract]
WHERE item_id = 184
) and x.eff_dt = (select max(eff_dt) from contract_ndc_brg where contract_num_val = (
SELECT item_name
FROM [contract]
WHERE item_id = 184
))
I figured out the problem with this is that it is returning the max date for any row.
How can I fix what I am doing wrong?
ROW_NUMBER() is your friend:
with q as
(
SELECT x.ndc_id
,z.attr_val AS trade_name
,x.quote_price
,x.eff_dt
,row_number() over (partition by nc_id order by eff_dt desc) rn
FROM contract_ndc_brg x
LEFT JOIN ndc_attr AS z ON z.field_id = 150
where contract_num_val = (
SELECT item_name
FROM [contract]
WHERE item_id = 184
)
)
select nc_id, trade_name, quote_price, eff_dt
from q
where rn = 1

Alternative solution for below SQL Query ,TableMasterID NOT IN take so much time

Need alternative solution for below SQL Query ,TableMasterID NOT IN take so much time, If i remove AND TableMasterID NOT IN
(SELECT DISTINCT c.TableMasterID
FROM ComFinalDataBS as C
WHERE C.ComFileID IN
(SELECT Number FROM fn_SplitInt(#ComFileID,','))) text from below query then getting result in 20 seconds otherwise result getting arround 4 minus.
SELECT A.SubTitleId,TableMasterID from SubTitle as A JOIN ComTableMaster as B ON a.SubTitle = b.TblName AND TableMasterID NOT IN (SELECT DISTINCT c.TableMasterID
FROM ComFinalDataBS as C
WHERE C.ComFileID IN
(SELECT Number FROM fn_SplitInt(#ComFileID,','))) AND B.TableMasterID IN
(SELECT DISTINCT d.TableMasterID
FROM ComData as D
WHERE D.ComFileID IN
(SELECT Number FROM fn_SplitInt(#ComFileID,','))) ORDER BY A.MainTitleID
SELECT A.SubTitleId ,
TableMasterID
FROM SubTitle AS A
JOIN ComTableMaster AS B ON A.SubTitle = B.TblName
WHERE NOT EXISTS ( SELECT 1
FROM ComFinalDataBS C
WHERE TableMasterID = C.TableMasterID
AND C.ComFileID IN (
SELECT Number
FROM MEFCampus..fn_SplitInt(#ComFileID, ',') ) )
AND NOT EXISTS ( SELECT 1
FROM ComData D
WHERE TableMasterID = D.TableMasterID
AND D.ComFileID IN (
SELECT Number
FROM MEFCampus..fn_SplitInt(#ComFileID,
',') ) )
AND B.IsDeleted = 0
ORDER BY MainTitleID
Have you tried storing the result from the fn_split_string() into an indexed temp-table first? It should help the Query Optimizer a lot.
SELECT DISTINCT Number
INTO #ComFileID
FROM dbo.fn_SplitInt(#ComFileID,',')
CREATE UNIQUE CLUSTERED INDEX uq0_ComFileID ON #ComFileID (Number) WITH (FILLFACTOR = 100)
SELECT A.SubTitleId,TableMasterID
FROM SubTitle as A
JOIN ComTableMaster as B
ON a.SubTitle = b.TblName
/*
AND B.TableMasterID NOT IN (SELECT DISTINCT c.TableMasterID
FROM ComFinalDataBS as C
JOIN #ComFileID CFI
ON CFI.Number = C.ComFileID )
*/
AND NOT EXISTS ( SELECT *
FROM ComFinalDataBS as C
JOIN #ComFileID CFI
ON CFI.Number = C.ComFileID
WHERE c.TableMasterID = B.TableMasterID )
/*
AND B.TableMasterID IN (SELECT DISTINCT d.TableMasterID
FROM ComData as D
JOIN #ComFileID CFI
ON CFI.Number = D.ComFileID
*/
AND EXISTS ( SELECT *
FROM ComData as D
JOIN #ComFileID CFI
ON CFI.Number = D.ComFileID
WHERE D.TableMasterID = B.TableMasterID )
ORDER BY A.MainTitleID

SQL Select Into #Temp

I have a complex SQL query that works. It's like
SELECT * FROM Site s
JOIN (
SELECT DISTINCT z.Value FROM Doc z
JOIN (
SELECT x.DocumentID FROM Doc x
JOIN (
SELECT DocumentID, MAX(VERSION) AS VERSION
FROM Doc GROUP BY DocumentID) y ON y.DocumentID = x.DocumentID
WHERE DocumentTypeID = 78 AND MetadataTypeID = 22 AND VALUE > GETDATE() AND y.Version = x.Version
) a ON z.DocumentID = a.DocumentID
WHERE MetadataTypeID = 2
) b ON b.Value = s.SiteID
WHERE SiteID > 0
It does what I want it to do. But when I wrap it in
SELECT * INTO #Temp FROM ()
I get an incorrect syntax near ')'.
I'm confused. I just want to put the results into a temp table so I can do further work on it. Why doesn't it work?
You're missing an alias for subquery.
SELECT * INTO #MyTempTable
FROM
(
SELECT * FROM Site s
JOIN (
SELECT DISTINCT z.Value FROM Doc z
JOIN (
SELECT x.DocumentID FROM Doc x
JOIN (
SELECT DocumentID, MAX(VERSION) AS VERSION
FROM Doc GROUP BY DocumentID) y ON y.DocumentID = x.DocumentID
WHERE DocumentTypeID = 78 AND MetadataTypeID = 22 AND VALUE > GETDATE() AND y.Version = x.Version
) a ON z.DocumentID = a.DocumentID
WHERE MetadataTypeID = 2
) b ON b.Value = s.SiteID
WHERE SiteID > 0
) AS DT
select * into TBL_name from
( SELECT * FROM Site s
JOIN (
SELECT DISTINCT z.Value FROM Doc z
JOIN (
SELECT x.DocumentID FROM Doc x
JOIN (
SELECT DocumentID, MAX(VERSION) AS VERSION
FROM Doc GROUP BY DocumentID) y ON y.DocumentID = x.DocumentID
WHERE DocumentTypeID = 78 AND MetadataTypeID = 22 AND VALUE > GETDATE() AND y.Version = x.Version
) a ON z.DocumentID = a.DocumentID
WHERE MetadataTypeID = 2
) b ON b.Value = s.SiteID
WHERE SiteID > 0)al

SQL - UNION, priority on the first select statement when doing order by

I'm trying to print out the results from the "GermanDB" Database first, while also showing everything from the Boston DB that was not in the German database. Can this be done in one query?
My query (the bold part functions but does not order the way I want)
select * from (
SELECT DISTINCT a.ProductRef
FROM GERMANDB.dbo.LOCATIONS AS a INNER JOIN GERMANDB.dbo.ITEMS AS b ON a.ProductRef = b.ProductRef
WHERE b.ACTIVE=1
) ta
UNION select * from
SELECT DISTINCT c.ProductRef
FROM BOSTONDB.dbo.LOCATIONS AS c INNER JOIN BOSTONDB.dbo.ITEMS AS d ON c.ProductRef = d.ProductRef
WHERE c.ACTIVE=1 (c.ProductRef NOT IN
(SELECT ProductRef FROM GERMANDB.dbo.ITEMS where ACTIVE=1))
) tb
order by ta.ProductRef** , tb.productRef
Just add one field to signal the priority. Like this:
select *, 0 as Priority from (
SELECT DISTINCT a.ProductRef
FROM GERMANDB.dbo.LOCATIONS AS a INNER JOIN GERMANDB.dbo.ITEMS AS b ON a.ProductRef = b.ProductRef
WHERE b.ACTIVE=1
) ta
UNION select *, 1 as Priority from
SELECT DISTINCT c.ProductRef
FROM BOSTONDB.dbo.LOCATIONS AS c INNER JOIN BOSTONDB.dbo.ITEMS AS d ON c.ProductRef = d.ProductRef
WHERE c.ACTIVE=1 (c.ProductRef NOT IN
(SELECT ProductRef FROM GERMANDB.dbo.ITEMS where ACTIVE=1))
) tb
order by Priority, ProductRef