TSQL conditional join for values in second table - sql-server-2008

I want to do conditional join on two tables and wanted to join with highest status in the second table. The status values are Assigned, Booked, Delivery and Closed.
SELECT
CPC.CpcID, StatusFlow = CPC.Status, Orders.CarModel, EnquiryLog.EnquiryStatus
FROM
CPC
INNER JOIN
Orders ON CPC.CpcID = Orders.CpcID
INNER JOIN
EnquiryLog ON CPC.CpcID = EnquiryLog.CpcID
WHERE
CPC.CpcID = '24092015/12'
So in this case it should show only one row with EnquiryStatus 'Delivery' but based on my query the result is:
SQL query output:

If I got it the right way:
SELECT CPC.CpcID, StatusFlow = CPC.Status, Orders.CarModel, ca.EnquiryStatus
FROM CPC
INNER JOIN Orders ON CPC.CpcID = Orders.CpcID
CROSS APPLY(SELECT TOP 1 * FROM EnquiryLog WHERE CPC.CpcID = EnquiryLog.CpcID
ORDER BY CASE EnquiryStatus
WHEN 'CLOSED' THEN 1
WHEN 'DELIVERY' THEN 2
WHEN 'BOOKED' THEN 3
WHEN 'ASSIGNED' THEN 4 END) ca
WHERE CPC.CpcID='24092015/12'

Related

how to select count of specific value while joining two tables

here i am joining two tables and this code fails to get the count of c.status
when c.status='Absent'
SELECT d.empReferenceID,
Count(c.status)
FROM emp_tbl d
LEFT JOIN empattendance c
on d.empReferenceID = c.RefrenceID
and c.status='PRESENT'
and month(c.CreatedOn)=5
and year(c.CreatedOn)=2017
where c.RefrenceID not in ('2075671')
GROUP BY d.empReferenceID;
Don't put conditions on an outer-joined table in the WHERE clause. Your where c.RefrenceID not in ('2075671') dismisses all outer-joined records and turns the join into an inner join.
Maybe you are looking for conditional aggregation, where you count different statuses and show the counts in the same result row:
SELECT d.empReferenceID,
Count(c.status) AS count_all,
Sum(c.status = 'PRESENT') AS count_present,
Sum(c.status = 'Absent') AS count_absent
FROM emp_tbl d
LEFT JOIN empattendance c
ON d.empReferenceID = c.RefrenceID
AND month(c.CreatedOn)=5
AND year(c.CreatedOn)=2017
WHERE d.empReferenceID not in ('2075671')
GROUP BY d.empReferenceID;
The SUM lines make use of MySQL's true = 1/ false = 0 by the way. You'd achieve the same with standard SQL: Sum(CASE WHEN c.status = 'PRESENT' THEN 1 ELSE 0 END) or Count(CASE WHEN c.status = 'PRESENT' THEN 1 END).

How to combine two sql counts from same joined table

another annoying student here!
Today I spend hours trying to combine (select) 2 already joined SQL outputs + the ID of the original table in a single table output. which ultimately resulted in this query:
SELECT * FROM(
SELECT fd1.User_idUser,avg(fd1.caloryIntake)
AS 'workdays'
FROM fact_dailysnapshot fd1
INNER JOIN dim_day dd1 ON dd1.DATE_SK = fd1.DATE_SK
WHERE dd1.weekend_ind = 'N'
GROUP BY fd1.User_idUser
ORDER BY fd1.User_idUser) A,
(SELECT avg(fd1.caloryIntake) AS 'weekend'
FROM fact_dailysnapshot fd1
INNER
JOIN dim_day dd1 ON dd1.DATE_SK = fd1.DATE_SK
WHERE dd1.weekend_ind = 'Y'
GROUP BY fd1.User_idUser
ORDER BY fd1.User_idUser) B;
Which translates into…
Now this is a false result, the second column gives an almost constant value for all user entries. I think this must be solved with some kind of EXTRA join but I literally ran out of ideas. Thanks in advance..!
Your JOIN is missing an ON clause to relate dUser_idUser.
But, the simplest way to write the query uses conditional aggregation:
SELECT fd1.User_idUser,
avg(case when dd1.weekend_ind = 'N' then fd1.caloryIntake end) as weekday_avg,
avg(case when dd1.weekend_ind = 'Y' then fd1.caloryIntake end) as weekend_avg
FROM fact_dailysnapshot fd1 INNER JOIN
dim_day dd1
ON dd1.DATE_SK = fd1.DATE_SK
GROUP BY fd1.User_idUser
ORDER BY fd1.User_idUser;
This is one query instead of two.
If I understand correctly, this is what you are looking for:
SELECT A.User_idUser, A.workdays, B.weekend
FROM (
SELECT fd1.User_idUser, avg(fd1.caloryIntake) AS 'workdays'
FROM fact_dailysnapshot fd1
INNER JOIN dim_day dd1
ON dd1.DATE_SK = fd1.DATE_SK
WHERE dd1.weekend_ind = 'N'
GROUP BY fd1.User_idUser
ORDER BY fd1.User_idUser) A
JOIN
(SELECT fd1.User_idUser, avg(fd1.caloryIntake) AS 'weekend'
FROM fact_dailysnapshot fd1
INNER JOIN dim_day dd1
ON dd1.DATE_SK = fd1.DATE_SK
WHERE dd1.weekend_ind = 'Y'
GROUP BY fd1.User_idUser
ORDER BY fd1.User_idUser) B
ON A.User_idUser = B.User_idUser
Each query gives you all users by ID and their workdays or weekends. You need to JOIN the results of the two query on the user ID.

How to count the results of a where clause in order to calculate a proportion a MYSQL select clause?

I'm starting out with this query, which gives me back 8 records with a "claimed" status. I'm looking to see if any of the addresses in the invites-from-address column are different from that in the moves-from-address column :
SELECT i.id, i.company_id, i.status,
ia_f.base_street as "invites-from-address", a_f.base_street as "moves-from-address",
ia_t.base_street as "invites-to-address", a_t.base_street as "moves-to-address", i.`mover_first_name`,
i.mover_last_name, i.`to_address_id`
FROM invites i
JOIN moves m ON i.id = m.`claimed_invite_id`
JOIN `invite_addresses` ia_f ON ia_f.id = i.`from_address_id`
JOIN addresses a_f ON a_f.id = m.from_address_id
JOIN `invite_addresses` ia_t ON ia_t.id = i.to_address_id
JOIN addresses a_t ON a_t.id = m.to_address_id
WHERE i.`company_id` = 1040345
GROUP BY id
What I'm trying to do in this query below is to create an average_discrepancy column on the fly that shows the proportion of addresses that differ between invites-from-address and moves-from-address. I was able to successfully check for address discrepancies by using a WHERE clause that checks that ia_f.base_street is not equal to a_f.base_street (which are aliased to the columns invites-from-address and moves-from-address respectively) but when I put this WHERE clause inside the count function in my SELECT cause it doesn't work. Is it because I can't place a WHERE clause inside a SELECT or a count function or both? And is there also a problem with trying to divide the results of two calls to the count function in my SELECT clause ?
SELECT i.id, i.company_id, i.status,
count(WHERE ia_f.base_street != a_f.base_street)/count(i.status="claimed") as "average_discrepancy",
ia_f.base_street as "invites-from-address", a_f.base_street as "moves-from-address",
ia_t.base_street as "invites-to-address", a_t.base_street as "moves-to-address",
i.`mover_first_name`,
i.mover_last_name, i.`to_address_id`
FROM invites i
JOIN moves m ON i.id = m.`claimed_invite_id`
JOIN `invite_addresses` ia_f ON ia_f.id = i.`from_address_id`
JOIN addresses a_f ON a_f.id = m.from_address_id
JOIN `invite_addresses` ia_t ON ia_t.id = i.to_address_id
JOIN addresses a_t ON a_t.id = m.to_address_id
WHERE i.`company_id` = 1040345
AND i.status = "claimed"
You need to put this into a SUM instead of a COUNT. Something like this would do the trick:
SELECT i.id, i.company_id, i.status,
SUM(CASE WHEN ia_f.base_street != a_f.base_street THEN 1 ELSE 0 END)/ SUM(CASE WHEN i.status='claimed' THEN 1 ELSE 0 END) as 'average_discrepancy',
ia_f.base_street as 'invites-from-address',
a_f.base_street as 'moves-from-address',
ia_t.base_street as 'invites-to-address',
a_t.base_street as 'moves-to-address',
i.mover_first_name,
i.mover_last_name,
i.to_address_id
FROM invites i
JOIN moves m ON i.id = m.claimed_invite_id
JOIN invite_addresses ia_f ON ia_f.id = i.from_address_id
JOIN addresses a_f ON a_f.id = m.from_address_id
JOIN invite_addresses ia_t ON ia_t.id = i.to_address_id
JOIN addresses a_t ON a_t.id = m.to_address_id
WHERE i.company_id = 1040345
AND i.status = 'claimed'

Adding a further condition to a 3 table query in Mariadb

Current query
SELECT vcc.name AS item, vcc.prodid, vcc.quantity AS qty,
UPPER(vcc.custom_message) AS nickname, vfd1.value AS fullname,
vfd2.value as email, vcc.purchaseid, vcc.price
FROM vxu_4_wpsc_cart_contents AS vcc INNER JOIN
vxu_4_wpsc_submited_form_data AS vfd1
ON vcc.purchaseid = vfd1.log_id AND vfd1.form_id = 2 INNER JOIN
vxu_4_wpsc_submited_form_data AS vfd2
ON vcc.purchaseid = vfd2.log_id AND vfd2.form_id = 9
I'm wanting to add the condition that the value in column 'processed' on table 'vxu_4_wpsc_purchase_logs is '2', so that only completed sales are returned. I'm struggling with the logic / syntax. Hope the image is readable.
Try this one. I've joined table purchase_logs by id and filtered result set by column processed with value equal 2
SELECT vcc.name AS item,
vcc.prodid,
vcc.quantity AS qty,
UPPER(vcc.custom_message) AS nickname,
vfd1.value AS fullname,
vfd2.value as email,
vcc.purchaseid,
vcc.price
FROM vxu_4_wpsc_cart_contents AS vcc
INNER JOIN vxu_4_wpsc_submited_form_data AS vfd1 ON vcc.purchaseid = vfd1.log_id
AND vfd1.form_id = 2
INNER JOIN vxu_4_wpsc_submited_form_data AS vfd2 ON vcc.purchaseid = vfd2.log_id
AND vfd2.form_id = 9
INNER JOIN vxu_4_wpsc_purchase_logs AS wpl ON wpl.id = vcc.purchaseid
WHERE wpl.processed = 2

Combining two queries in mySQL

I'm trying to combine the results of two queries. I'm not very proficient in mysql so I'm here for some help.
The first query is as follows:
select count(roomtypeid) as bookedrooms, day
from event_guest_hotel
where hotelid = 1 and roomtypeid = 1
group by day;
This returns:
The second query:
SELECT ehr.reservationid, ehr.day, h.name AS hotelname,
ehr.totalrooms as requested_rooms, r.name AS roomname
FROM event_hotel_reservation ehr
INNER JOIN hotel_room_type r
ON ehr.roomtypeid = r.roomtypeid
INNER JOIN hotel h
ON ehr.hotelid = h.hotelid
WHERE totalRooms != 0
AND reservationID = '1'
This returns:
Can I combine the first query with the second one, so I get the results of the first one in another resultcolumn next to 'roomname'? That way I know how many rooms are already booked and how many were originally requested from one single query.
Try:
SELECT ehr.reservationid, ehr.day, h.name AS hotelname,
ehr.totalrooms as requested_rooms, r.name AS roomname,
egh.bookedrooms
FROM event_hotel_reservation ehr
INNER JOIN hotel_room_type r ON ehr.roomtypeid = r.roomtypeid
INNER JOIN hotel h ON ehr.hotelid = h.hotelid
left outer join (
select hotelid, count(roomtypeid) as bookedrooms, day
from event_guest_hotel
where roomtypeid = 1
group by hotelid, day
) egh on h.hotelid = egh.hotelid and ehr.day = egh.day
WHERE totalRooms != 0
AND reservationID = '1'