multiple joined query with propel - database

Let's consider following tables:
special_product(
id
product_key - FK to product.key)
product(
id
key
name)
product_attributes(
id
product_id FK to product.id
description
)
My question is how could I write a query that would provide me columns special_product.id, product.id, product_attributes.description starting from the SpecialProductQuery class.
Basically the generated query should be
select s.id, p.id, pa.description
from special_product s
left join product p on s.key = p.key
left join product_attributes pa on p.id = pa.product_id

Assuming that you've got the relationships build out in your schema you should just be able to do:
$specialProduct = specialProductQuery::create()
->joinWithProduct(SpecialProduct.Product)
->joinWith(Product.ProductAttributes)
->find();
From here you can get whichever of the values you need from the sub-objects (keep in mind you still need to iterate through the collection):
foreach($specialProduct as $special)
{
$product = $special->getProduct();
}
YMMV depending on how you've named out your model.

Related

SQL Views on multiple tables

I have a database of a Travel Agency which contains tables Hotel, Motel and RentalHome, all of which refer to the Accommodation table using a foreign key that references the
accommodation_id of that table.
I wish to create a View so that I can identify what a particular accommodation ID refers to; Hotel, Motel, or RentalHome.
CREATE VIEW IdentifyAccom AS
SELECT Accommodation.accom_id AS AccomID, Hotel.hotel_name AS Hotel_Name
FROM Accommodation, Hotel
WHERE Accommodation.accom_id = Hotel.accom_id
How can I go about this? I tried the following approach but to no avail.
CREATE VIEW IdentifyAccom AS
SELECT Accommodation.accom_id AS AccomID, Hotel.hotel_name AS Hotel_Name, Motel.motel_name
FROM Accommodation, Hotel, Motel
WHERE Accommodation.accom_id = Hotel.accom_id,
WHERE Accommodation.accom_id = Motel.accom_id
Presumably all accomodations are either a Hotel or a Motel? If so you can use something like IIF to determine the type and ISNULL or COALESCE to populate a name.
CREATE VIEW IdentifyAccom
AS
SELECT a.accom_id AS AccomID, IIF(h.accom_id IS NOT NULL, 'HOTEL', 'MOTEL') AS Accom_Type,
ISNULL(h.hotel_name, m.motel_name) AS Accom_Name
FROM Accommodation a
LEFT JOIN Hotel h ON h.accom_id = a.accom_id
LEFT JOIN Motel m ON m.accom_id = a.accom_id
Try with inner join
CREATE VIEW IdentifyAccom AS
SELECT
A.accom_id AS AccomID
,H.hotel_name AS Accom
FROM Accommodation A
INNER JOIN Hotel H ON H.accom_id = A.accom_id
UNION
SELECT
A.accom_id AS AccomID
,M.motel_name AS Accom
FROM Accommodation A
INNER JOIN Motel M ON M.accom_id = A.accom_id

SQL Server Index over lookup table of distinct values

I am trying to speed up the following SQL Server query:
SELECT
V.Id, V.Number, V.VisitDate, V.ArrivalTime, V.VisitKindId, VK.Description AS
VisitKindDescription,
VK.DescriptionAr AS VisitKindDescriptionAr, V.StatusId, V.Note, V.CancelingReason,
V.CancelingTime, V.EnterToDoctorRoomTime,
V.PatientId, P.Number AS PatientNumber, P.FirstName, P.LastName, P.BirthDate, P.Note AS
PatientNotes, V.DoctorId, D.FullName AS DoctorFullName, V.CreatedById,
U.FullName AS UserFullName, V.CreationDate, V.VersionNo
FROM
Patient_Tbl P INNER JOIN
Visit_Tbl V ON P.Id = V.PatientId INNER JOIN
VisitKind_Tbl VK ON V.VisitKindId = VK.Id INNER JOIN
Doctor_Tbl D ON V.DoctorId = D.Id INNER JOIN
User_Tbl U ON V.CreatedById = U.Id INNER JOIN
VisitStatus_Tbl VS ON V.StatusId = VS.Id
WHERE V.StatusId = 2 --patient is in doctor room
and we had the following 4 values the VisitStatus_Tbl:
(1 -> In Waiting Room, 2 -> In Doctor Room, 3 -> Canceled, 4 -> Completed)
and in one moment of time, there is only one record on the Visits table for one person in the doctor's room.
The end-user inform me that there is a delay in the use case that depends on the above query.
Please help us speed system performance by suggesting the proper index.
Thanks,
You do not indicate if you have any indexes on the tables now. I will assume that the 'ID' columns for patient_tbl, etc are clustered primary keys or just primary keys and have indexes. If not, that is another problem.
Simple rule: start with index foreign keys (lookup tables) and WHERE clauses.
CREATE INDEX ix_visit_tbl_statusid ON visit_tbl(statusId)
CREATE INDEX ix_visit_tbl_patientid ON visit_tbl(patientId)
CREATE INDEX ix_visit_tbl_visitkindId ON visit_tbl(visitkindId)
CREATE INDEX ix_visit_tbl_doctorid ON visit_tbl(doctorId)
CREATE INDEX ix_visit_tbl_createdbyid ON visit_tbl(createdbyId)
Now for the comments on how that is too many indexes. It depends ...

When a SQL Server query returns no rows(NOT null rows) how do you include that in an aggregate function?

I'm writing a query to look for courses that do not have any of its gradable items graded.
In Blackboard when a user doesn't have a grade at all(e.g. no attempt was ever made) there simply isn't a row in the table gradebook_grade
So if a course doesn't have any grades at all the gradebook_grade table does not have any rows referencing the primary key of the Blackboard course_id
This is what I've used so far:
use bblearn
select cm.course_id
from course_main cm
join gradebook_main gbm on cm.pk1 = gbm.crsmain_pk1
join gradebook_grade gbg on gbm.pk1 = gbg.gradebook_main_pk1
where cm.pk1 = 3947
group by cm.course_id
having count(gbg.pk1) <= 0
The course in question(pk1 3947) is confirmed to not have any grades. So SQL Server says 0 rows affected, naturally.
The thing is, it doesn't select the course_id. I'm guessing having doesn't account for blank/non-existent rows. Is there a way to structure the query to get the course ID when there isn't anything returned? Am I joining on the wrong columns or using where on the wrong column? Any help is appreciated.
Use a left join
select cm.course_id
from course_main cm
left join gradebook_main gbm on cm.pk1 = gbm.crsmain_pk1
left join gradebook_grade gbg on gbm.pk1 = gbg.gradebook_main_pk1
where cm.pk1 = 3947
group by cm.course_id

Counting grouped records from multiple tables

there is a column comment_id of a table called pic_alb_love which i'd like to add to the query below but i don't know how. Actually what i want to do is to count the total comment_id of the table pic_alb_love.
SELECT users_pics.wardrobe,
profile.fname,
users_pics.pic,
users_pics.u_pic_id,
users_pics.email,
users_pics.make,
users_pics.designer,
photo_comment.comment,
max_photo_comment.count_pic_id
FROM dbo.users_pics
INNER JOIN profile
ON users_pics.email = profile.email
LEFT Join (SELECT pic_id
,MAX(comment_id) max_comment_id
,COUNT(pic_id) count_pic_id
FROM photo_comment
GROUP BY pic_id
) max_photo_comment
On users_pics.u_pic_id = max_photo_comment.pic_id
LEFT Join photo_comment
On max_photo_comment.pic_id = photo_comment.pic_id
AND max_photo_comment.max_comment_id = photo_comment.comment_id
WHERE users_pics.wardrobe = MMColParam
AND users_pics.email = MMColParam2
ORDER BY u_pic_id asc
these are the various fields of the table pic_alb_love:
(comment_id,pic,love_com, wardrobe, email
,com_name,resp_email, play_count, com_stat)
LEFT JOIN (SELECT Pic
,Count(*) [CommentCount]
FROM pic_alb_love
GROUP BY Pic) c
ON c.Pic=u_pic_id
Assuming that pic_alb_love.pic is the FK on the table...
Use [CommentCount] in the select list.

LINQ entity from database view with MANY to MANY relation

i have a problem. I have a database view with many to many relation, it looks like this
SELECT TOP (100) PERCENT dbo.PostAdditional.Description, dbo.PostAdditional.Summary, dbo.PostAdditional.Title, dbo.Post.PostID, dbo.Post.Type, dbo.Tags.TagID, dbo.Tags.TagName,
FROM dbo.Post
INNER JOIN dbo.PostAdditional ON dbo.Post.PostID = dbo.PostAdditional.PostID
INNER JOIN dbo.PostWithTags ON dbo.Post.EventID = dbo.PostWithTags.PostID
INNER JOIN dbo.Tags ON dbo.PostWithTags.TagID = dbo.Tags.TagID
ORDER BY dbo.Post.StartDate, dbo.Post.PubDate
I want to use LINQ to SQL to work with it. When I normaly put this view in DBML designer, it creates an entity. But entity has proterty TagName as String, and I want it as array of tag names (or better List<>). When I take data from database, i get one copy of Post entity for evry single tag, but I want to get one Post entity with array of all tags associated.
Maybe this will help:
I changed this join from
INNER JOIN dbo.PostWithTags ON dbo.Post.EventID = dbo.PostWithTags.PostID
To
INNER JOIN dbo.PostWithTags ON dbo.Post.PostID = dbo.PostWithTags.PostID
And if I understand you right is this what you want?
var test=
(
from p in db.Post
orderby p.StartDate,p.PubDate
select new
{
p.PostID,
p.Type,
Tags=
(
from pa in db.PostAdditional
join pwt in db.PostWithTags
on pa.PostID equals pwt.PostID
join t in db.Tags
on pwt.TagID equals t.TagID
where p.PostID == pa.PostID
select new
{
pa.Description,
pa.Summary,
pa.Title,
t.TagID,
t.TagName
}
)
}
).ToList();
Where db is the databasecontext

Resources