SQL -- Adding a constraint to a results row in an existing query - sql

The following query gives me a one row result
Select Sum(Actions) From
(
Select
Count(t.Create_Dtime) As Actions
From Player_Tapjoy T
Inner Join Player_Source S
On (T.Player_Id = S.Player_Id)
Inner Join Feature_Group_Xref F
On (S.Group_Id=F.Group_Id
And F.Feature_Name ='Try BC')
Where Trunc(t.Create_Dtime) = To_Date('2012-sep-17','yyyy-mon-dd')
Union All
Select
Count(a.Create_Dtime) As Actions
From Player_Aux_Pt A
Inner Join Player_Source S
On (A.Player_Id = S.Player_Id)
Inner Join Feature_Group_Xref F
On (S.Group_Id=F.Group_Id
and f.feature_name = 'TryBC')
Where A.Site = 'AppCircle'
And Trunc(A.Create_Dtime) = To_Date('2012-sep-17','yyyy-mon-dd')
)
I now want to add in a constraint to the result where: only users that have created an account before Sep 12,2012.
In my database language: only users that have a trunc(create_dtime) < To_Date('2012-sep-12','yyyy-mon-dd') . This trunc(create_dtime) date comes from the player table.
Could I map this player table to the current table by using another inner join?

Your requirement isn't completely clear and obviously I have had to guess about your data model. I'm assuming the Player table has one row per Player_Id i.e. it is the primary key end of foreign key relationships to the tables you're querying.
I have changed the inner query so it just returns a set of rows rather than aggregations. Then I join the inline view (aliased q) with the Player table and use a COUNT() rather a SUM() to get the figure.
Select count(Player_Id) From
(
Select
T.Player_Id
From Player_Tapjoy T
Inner Join Player_Source S
On (T.Player_Id = S.Player_Id)
Inner Join Feature_Group_Xref F
On (S.Group_Id=F.Group_Id
And F.Feature_Name ='Try BC')
Where Trunc(t.Create_Dtime) = To_Date('2012-sep-17','yyyy-mon-dd')
Union All
Select
A.Player_Id
From Player_Aux_Pt A
Inner Join Player_Source S
On (A.Player_Id = S.Player_Id)
Inner Join Feature_Group_Xref F
On (S.Group_Id=F.Group_Id
and f.feature_name = 'TryBC')
Where A.Site = 'AppCircle'
And Trunc(A.Create_Dtime) = To_Date('2012-sep-17','yyyy-mon-dd')
) q
join player p
on (p.Player_Id = q.Player_Id)
where Trunc(p.Create_Dtime) < To_Date('2012-sep-12','yyyy-mon-dd')
This may not be the exact result you need, for the reasons I gave at the top, but it should point you in the right directon.

Related

SQL SERVER: JOIN 2 already joined sections of tables

I already LEFT JOINed many tables into two sections, but now how do I join these two together?
I am not sure if subquery would work but at least I tried subquery its very confused/
SELECT MoviePerson.PersonId, MoviePerson.PersonFirstName, MoviePerson.PersonLastName, MoviePersonRole.RoleId FROM MoviePerson
LEFT JOIN MoviePersonRole ON MoviePerson.PersonId = MoviePersonRole.PersonId;
select DVD.DVDId, DVD.GenreId, DVD.RatingId, DVD.DVDTitle, DVD.DVDReleasedate, DVD.TheaterReleaseDate, Genre.GenreName, Rating.RatingName,
Rating.RatingDescription
from DVD
LEFT join Genre on DVD.GenreId = Genre.GenreID
LEFT JOIN Rating ON DVD.RatingId = Rating.RatingId
LEFT JOIN MoviePersonRole ON DVD.DVDId =MoviePersonRole.DVDId
;
db<>fiddle
It doesn't look as though you have a column to join on. If you did, you could use the following syntax:
SELECT *
FROM
(
SELECT MoviePerson.PersonId, MoviePerson.PersonFirstName, MoviePerson.PersonLastName, MoviePersonRole.RoleId FROM MoviePerson
LEFT JOIN MoviePersonRole ON MoviePerson.PersonId = MoviePersonRole.PersonId;
) X
INNER JOIN
(
select DVD.DVDId, DVD.GenreId, DVD.RatingId, DVD.DVDTitle, DVD.DVDReleasedate, DVD.TheaterReleaseDate, Genre.GenreName, Rating.RatingName,
Rating.RatingDescription
from DVD
LEFT join Genre on DVD.GenreId = Genre.GenreID
LEFT JOIN Rating ON DVD.RatingId = Rating.RatingId
LEFT JOIN MoviePersonRole ON DVD.DVDId =MoviePersonRole.DVDId
) Y
ON X.column_to_join = y.column_to_join

How to build the SQL query for given question?

I have 2 SQL problems for which I need SQL query.
Table - Booking
Table - Adventure
Table - Tourist
Table - Location
Query1: Display TourId, TourName and Email of those tourist(s) who have booked all types of adventures. (Hint: Use the concept of Joins).
My Try:
Select DISTINCT T.TourId, T.TourName, T.Email
From Tourist T
INNER JOIN Booking B ON B.TourId = T.TourId
INNER JOIN Location L ON L.LocId = B.Loc
INNER JOIN Adventure A ON A.AdvId = L.AdvId
AND A.AdvType in (Select DISTINCT AdvType From Adventure)
Query2: For each booking, Identify the location whose bookingamount is greater than the average bookingamount of all the bookings done for that location. Display LocId, LocName and Rating for the identified location(s). (Hint: Use the concept of subqueries)
My Try:
Select B.Loc, L.LocName, L.Rating
From Booking B
INNER JOIN Location L ON B.Loc = L.LocId
AND BookingAmount > (Select AVG(B.BookingAmount) from Booking B Group By B.Loc)
Query 1:
select distinct tourid,tourname,email from tourist, booking, location
where 1=1
and tourist.tourid = booking.tourid
and booking.locid = location.locid
and location.advid = adventure.advid
and adventure.advtype = 'A'
Query 2:
select locid,locname,rating
from location
where locid in (select booking.locid from booking, (select
b.bookid,b.loc,avg(b.bookingamount) as avg_ba from booking b group by
b.bookid,b.loc) aa
where booking.bookid = aa.bookid and booking.loc = aa.loc and
booking.bookingamount > aa.avg_ba)
Note: if it is a database design for any production server, I must say it needs to be changed ASAP.
Another Note: Please do not ever use pictures as references. It is very difficult to get information from pictures
Query 1:-
Select DISTINCT T.TourId, T.TourName, T.Email
From Tourist T
INNER JOIN Booking B ON B.TourId = T.TourId
INNER JOIN Location L ON L.LocId = B.Loc
INNER JOIN Adventure A ON A.AdvId = L.AdvId
WHERE A.AdvType='A' AND A.AdvType='G' AND A.AdvType='W';
Query 2:-
Select B.Loc, L.LocName, L.Rating
From Booking B
INNER JOIN Location L ON B.Loc = L.LocId
WHERE B.BookingAmount > (Select AVG(B.BookingAmount) from Booking B Group By B.Loc);

Access Subquery On mulitple conditions

This SQL query needs to be done in ACCESS.
I am trying to do a subquery on the total sales, but I want to link the sale to the province AND to product. The below query will work with one or the other: (po.product_name = allp.all_products) AND (p.province = allp.all_province); -- but it will no take both.
I will be including every month into this query, once I can figure out the subquery on with two criteria.
Select
p.province as [Province],
po.product_name as [Product],
all_price
FROM
(purchase_order po
INNER JOIN person p
on p.person_id = po.person_id)
left join
(
select
po1.product_name AS [all_products],
sum(pp1.price) AS [all_price],
p1.province AS [all_province]
from (purchase_order po1
INNER JOIN product pp1
on po1.product_name = pp1.product_name)
INNER JOIN person p1
on po1.person_id = p1.person_id
group by po1.product_name, pp1.price, p1.province
)
as allp
on (po.product_name = allp.all_products) AND (p.province = allp.all_province);
Make the first select sql into a table by giving it an alias and join table 1 to table 2. I don't have your table structure or data to test it but I think this will lead you down the right path:
select table1.*, table2.*
from
(Select
p.province as [Province],
po.product_name as [Product]
--removed this ,all_price
FROM
(purchase_order po
INNER JOIN person p
on p.person_id = po.person_id) table1
left join
(
select
po1.product_name AS [all_products],
sum(pp1.price) AS [all_price],
p1.province AS [all_province]
from (purchase_order po1
INNER JOIN product pp1
on po1.product_name = pp1.product_name)
INNER JOIN person p1
on po1.person_id = p1.person_id
group by po1.product_name, pp1.price, p1.province --check your group by, I dont think you want pp1.price here if you want to aggregate
) as table2 --changed from allp
on (table1.product = table2.all_products) AND (table1.province = table2.all_province);

sql subquery join group by

I am trying to get a list of our users from our database along with the number of people from the same cohort as them - which in this case is defined as being from the same medical school at the same time.
medical_school_id is stored in the doctor_record table
graduation_dt is stored in the doctor_record table as well.
I have managed to write this query out using a subquery which does a select statement counting the number of others for each row but this takes forever. My logic is telling me that I ought to run a simple GROUP BY query once first and then somehow JOIN the medical_school_id on to that.
The group by query is as follows
select count(ca.id) , cdr.medical_school_id, cdr.graduation_dt
from account ca
LEFT JOIN doctor cd on ca.id = cd.account_id
LEFT JOIN doctor_record cdr on cd.gmc_number = cdr.gmc_number
GROUP BY cdr.medical_school_id, cdr.graduation_dt
The long select query is
select a.id, a.email , dr.medical_school_id,
(select count(ba.id) from account ba
LEFT JOIN doctor bd on ba.id = bd.account_id
LEFT JOIN doctor_record bdr on bd.gmc_number = bdr.gmc_number
WHERE bdr.medical_school_id = dr.medical_school_id AND bdr.graduation_dt = dr.graduation_dt) AS med_count,
from account a
LEFT JOIN doctor d on a.id = d.account_id
LEFT JOIN doctor_record dr on d.gmc_number = dr.gmc_number
If you could push me in the right direction that would be amazing
I think you just want window functions:
select a.id, a.email, dr.medical_school_id, dr.graduation_dt,
count(*) over (partition by dr.medical_school_id, dr.graduation_dt) as cohort_size
from account a left join
doctor d
on a.id = d.account_id left join
doctor_record dr
on d.gmc_number = dr.gmc_number;
Using your same code for group by:
SELECT * FROM (
(
SELECT acc.[id]
, acc.[email]
FROM
account acc
LEFT JOIN
doctor doc
ON
acc.id = doc.account_id
LEFT JOIN
doctor_record doc_rec
ON
doc.gmc_number = doc_rec.gmc_number
) label
LEFT JOIN
(
SELECT count(acco.id)
, doc_reco.medical_school_id
, doc_reco.graduation_dt
FROM
account acco
LEFT JOIN
doctor doct
ON
acco.id = doct.account_id
LEFT JOIN
doctor_record doc_reco
ON
doct.gmc_number = doc_reco.gmc_number
GROUP BY
doc_reco.medical_school_id,
doc_reco.graduation_dt
) count
ON
count.[medical_school_id]=label.[medical_school_id]
AND
count.[graduation_dt]=label.[graduation_date]
)
how about something like this?
select a.doctor_id
, count(*) - 1
from doctor_record a
left join doctor_record b on a.medical_school_id = b.medical_school_id
and a.graduation_dt = b.graduation_dt
group by a.doctor_id
Subtract 1 from the count so that you're not counting the doctor in the "other folks in same cohort" number
I'm defining "same cohort" as "same medical school & graduation date".
I'm unclear on what GMC number is and how it is related. Is it something to do with cohort?

SQL Multiple Joins not working as expected

I have following query not working when I try to join all 4 tables (It is taking over an hour to run, I have to eventually kill the query without any data being returned).
It works when Table 1,2 & 3 are joined AND Then If I try Table 1,2 & 4 join but not when I attempt to join all 4 tables below.
Select * From
(Select
R.ID, R.MId, R.RId, R.F_Name, R.F_Value, FE.FullEval, M.Name, RC.CC
FROM Table1 as R
Inner Join Table2 FE
ON R.ID = FE.RClId and R.MId = FE.MId and R.RId = FE.RId
Inner Join Table3 as M
ON R.MId = M.MId and FE.MId = M.MId
Inner Join Table4 as RC
ON R.RId = RC.RId and FE.RId = RC.RId and FE.Date = RC.Date
) AS a
NOTE:
1) RId is not available in table3.
2) MId is not available in table4.
Thanks for help.
Since you mentioned that you don't have permission to view the query plan, try breaking down into each table join. You can also check which table join is taking time to retrieve records. From there, you can investigate the data why it's taking time. It may be because of non-availability of column keys in Table 3 and Table 4?
WITH Tab1_2 AS
(SELECT r.ID, r.MId, r.RId, r.F_Name, r.F_Value, fe.FullEval, fe.date
FROM Table1 as r
INNER JOIN Table2 fe
ON r.ID = fe.RClId
AND r.MId = fe.MId
AND r.RId = fe.RId
WHERE ... -- place your conditions if any
),
Tab12_3 AS
(SELECT t12.*, m.Name
FROM Tab1_2 t12
INNER JOIN Table3 as m
ON t12.MId = m.MId
WHERE ... -- place your conditions if any
),
Tab123_4 AS
(SELECT t123.ID, t123.MId, t123.RId, t123.F_Name, t123.F_Value, t123.FullEval, rc.CC
FROM Tab12_3 t123
INNER JOIN Table4 as rc
ON t123.RId = rc.RId
AND t123.Date = rc.Date
WHERE ... -- place your conditions if any
)
SELECT *
FROM Tab123_4 t1234