Retrieving Records from Multiple Tables issue - sql

Hello i am making schema for purchasing orders these orders can be ordered by certain user and then received by another user.
The issue is when UserID value in Deliveries table is null the query return no records.
UserID value is null because the order is not Delivered yet.
Query
SELECT pu.FirstName as purchase_FirstName, pu.LastName as purchase_LastName,
du.FirstName as delivery_FirstName, du.LastName as delivery_LastName,
po.PurchaseOrderDate,
d.ExpectedDeliveryDate, d.ActualDeliveryDate
FROM dbo.PurchaseOrders po JOIN
dbo.Deliveries d
ON po.PurchaseOrderID = d.PurchaseOrderID JOIN
dbo.Users pu
ON po.UserID = pu.UserID JOIN
dbo.Users du
ON d.UserId = du.UserId;
Schema

Most likely you need a LEFT JOIN here. A little formatting makes this a LOT easier to read. You might take a look at this article to understand the different types of joins. http://blog.codinghorror.com/a-visual-explanation-of-sql-joins/
SELECT pu.FirstName as purchase_FirstName
, pu.LastName as purchase_LastName
, du.FirstName as delivery_FirstName
, du.LastName as delivery_LastName
, po.PurchaseOrderDate
, d.ExpectedDeliveryDate
, d.ActualDeliveryDate
FROM dbo.PurchaseOrders po
JOIN dbo.Users pu ON po.UserID = pu.UserID
left JOIN dbo.Deliveries d ON po.PurchaseOrderID = d.PurchaseOrderID
left JOIN dbo.Users du ON d.UserId = du.UserId;

Related

PostgreSQL select multiple columns of a table that is connected via a many-to-many pivot

I have this query:
SELECT
a.account_uuid,
a.account_no,
a.account_group_uuid,
a.account_scope_uuid,
a.created_at,
a.deleted_at,
s.service_uuid,
s.status,
st.service_type,
(
SELECT
c.company
FROM companies c
WHERE a.company_owner_uuid = c.company_uuid
)
FROM
accounts a
LEFT JOIN
services s
ON a.account_uuid = s.account_uuid
LEFT JOIN
service_types st
ON s.service_type_uuid = st.service_type_uuid
WHERE
a.deleted_at IS NULL
ORDER BY
a.account_no
And I need to join and select multiple columns from a people table by way of a pivot table accounts_contacts that would have the account_uuid and a person_uuid. There are also is_primary and is_active columns on the accounts_contacts table and there will only be one primary at a time, so the end result would be a single first and last name. This is the idea of the query:
SELECT
p.first_name, p.last_name
FROM
people p
INNER JOIN
accounts_contacts ac
ON ac.account_uuid = a.account_uuid
AND ac.person_uuid = p.person_uuid
WHERE
ac.is_primary = true
AND ac.is_active = true
But not sure how to fit it into the above query. A subquery would only allow for one of the columns.
account_contacts is an "association" or "junction" table. It is not a pivot table.
The basic idea should be joins:
SELECT . . . ,
p.first_name, p.last_name
FROM accounts a LEFT JOIN
services s
ON a.account_uuid = s.account_uuid LEFT JOIN
service_types st
ON s.service_type_uuid = st.service_type_uuid LEFT JOIN
accounts_contacts ac
ON ac.account_uuid = a.account_uuid LEFT JOIN
people p
ON ac.person_uuid = p.person_uuid AND
ac.is_primary = true AND
ac.is_active = true

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?

how to select some fields from tables in CakePHP

I tried to make query in cakephp with joins, but i want to get more fileds,
Here the query sql :
SELECT
sd.debut,
sd.fin,
fr.id,
f.id as formtaion_id,
s.id as seance_id,
fr.nom as formateur,
f.nom as formation,
r.title,
f.module,
sd.module as partie ,
f.couleur
FROM seances s
INNER JOIN formations f on s.formation_id = f.id
INNER JOIN seances_dates sd on s.id = sd.seance_id
INNER JOIN salles sa on sa.id = s.salle_id
INNER JOIN regions r on r.id = sa.region_id
INNER JOIN presence_formateurs pf ON pf.seance_id = s.id
INNER JOIN formateurs fr ON fr.id = pf.formateur_id
WHERE fr.archived = 0
AND fr.deleted is null
AND (
(sd.debut between '".$from."' and '".$to."')
OR
(sd.fin between '".$from."' and '".$to."')
)
GROUP BY sd.id
ORDER BY sd.debut
please help me to make that query in cakephp :
ClassRegistry::init('seance')->find('all'....
You should read very carefully
1. How to Retrieve data in CakePHP and
2. How to make Relation with different table

Query returns no records

Hello i am making schema for purchasing orders these orders can be ordered by certain user and then received by another user.
so i created the below schema.
Schema
The issue is when UserID column in PurchaseOrders and Deliveries tables has different values the query returns no records.
Query
SELECT
dbo.Users.FirstName,
dbo.Users.LastName,
dbo.PurchaseOrders.PurchaseOrderDate,
dbo.Deliveries.ExpectedDeliveryDate,
dbo.Deliveries.ActualDeliveryDate
FROM dbo.PurchaseOrders
INNER JOIN dbo.Users
ON dbo.PurchaseOrders.UserID = dbo.Users.UserID
INNER JOIN dbo.Deliveries
ON dbo.PurchaseOrders.PurchaseOrderID = dbo.Deliveries.PurchaseOrderID
AND dbo.Users.UserID = dbo.PurchaseOrders.UserID
AND dbo.Users.UserID = dbo.Deliveries.UserID
You need two different joins to Users. You also need to learn to use table aliases:
SELECT pu.FirstName as purchase_FirstName, pu.LastName as purchase_LastName,
du.FirstName as delivery_FirstName, du.LastName as delivery_LastName,
po.PurchaseOrderDate,
d.ExpectedDeliveryDate, d.ActualDeliveryDate
FROM dbo.PurchaseOrders po JOIN
dbo.Deliveries d
ON po.PurchaseOrderID = d.PurchaseOrderID JOIN
dbo.Users pu
ON p.UserID = pu.UserID JOIN
dbo.Users du
ON d.UserId = du.UserId;
Your query returns no records because of this condition:
AND dbo.Users.UserID = dbo.PurchaseOrders.UserID
AND dbo.Users.UserID = dbo.Deliveries.UserID
This obviously means that dbo.PurchaseOrders.UserID = dbo.Deliveries.UserID. So, if this is not true, then no records match the condition.
When you use Inner Join, if the data doesnt match, you will not get any records. You need to use LEFT JOIN and also the second join doesnt need condition with user id. Try the below query.
SELECT
dbo.Users.FirstName,
dbo.Users.LastName,
dbo.PurchaseOrders.PurchaseOrderDate,
dbo.Deliveries.ExpectedDeliveryDate,
dbo.Deliveries.ActualDeliveryDate
FROM dbo.PurchaseOrders
INNER JOIN dbo.Users
ON dbo.PurchaseOrders.UserID = dbo.Users.UserID
LEFT JOIN dbo.Deliveries
ON dbo.PurchaseOrders.PurchaseOrderID = dbo.Deliveries.PurchaseOrderID

Proper Syntax for 3 table SELECT query

I've got 3 tables:
tblPosts
tblComments
tblUsers
I'm trying to get a listing of Posts along with associated Comments. The tricky part seems to be getting the Posts and Comments to show the proper author (User). This is the closest I get but then the Posts authors are incorrect. I'm grouping my CFOutput on "pid", so I only get each post one time as I would expect.
SELECT tblPosts.pid
, tblPosts.title
, tblPosts.description
, tblPosts.price
, tblPosts.datecreated AS pdate
, tblPosts.image1
, tblComments.comment
, tblComments.datecreated AS cdate
, tblUsers.fname
, tblUsers.lname
FROM tblPosts
LEFT JOIN tblComments ON tblPosts.pid = tblComments.pid
LEFT JOIN tblUsers ON tblComments.uid = tblUsers.uid
Any thoughts?
Thanks!
Since both tables contain an author id, you must to JOIN to tblUser twice: once for posts and once for comments. That means you must use a table alias to differentiate between the two. Something along these lines, where pa is the alias for "Post Author" and ca the alias for "Comment Author".
SELECT p.pid
, p.title
, ...
, pa.fname AS PostAuthorFirstName
, pa.lname AS PostAuthorLastName
, ca.fname AS CommentAuthorFirstName
, ca.lname AS CommentAuthorLastName
FROM tblPosts p
LEFT JOIN tblUsers pa ON pa.uid = p.uid
LEFT JOIN tblComments c ON p.pid = c.pid
LEFT JOIN tblUsers ca ON ca.uid = c.uid
I'm not familiar with all the fields in you tables. Join the post to the users table as well to get the specific users for writing posts.
How about trying this:
SELECT p.pid
,p.title
,p.description
,p.price
,p.datecreated AS pdate
,p.image1
,c.comment
,c.datecreated AS cdate
,u1.fname AS CommentAuthorsName
,u1.lname AS CommentAuthorsLastName
,u2.fname AS PostAuthorName
,u2.lname AS PostAuthorLastName
FROM tblPosts p
LEFT JOIN tblComments c
ON p.pid = c.pid
LEFT JOIN tblUsers u1
ON c.uid = u1.uid
LEFT JOIN tblUsers u2
ON p.uid = u2.uid