MySQL - subquery or joining multiple rows - mysql

I got a little struggle with my mysql query. Maybe someone can help me.
Tables:
contacts:
|id|phone|first_name|last_name|email|company|
custom_values:
|id|c_id|custom_field_id|value|
The table custom_values got different custom_field_ids
id 4 = mobile
id 5 = fax
id 20 = 2nd phonenumber
The current query gives me all information from my contacts table.
concat(contacts.first_name, ' ', contacts.last_name, ' - ', contacts.company) as displayname, contacts.phone, contacts.last_name, contacts.first_name, contacts.company, contacts.email
from contacts
Now I want to add the information from the custom_values table to the query above.
Is it possible to add 3 rows, that adds me mobile, fax and the 2nd phonenomber to every contact?
I tried with the next query, but that doesn´t work.
SELECT
concat(contacts.first_name, ' ', contacts.last_name, ' - ', contacts.company) as displayname, contacts.phone, contacts.last_name, contacts.first_name, contacts.company, contacts.email,custom_values.value as mobile
from custom_values
join contacts on custom_values.customized_id = contacts.id
where custom_values.custom_field_id=4
thanks guys.

If you want additional rows, then your approach is fine. However, I think you want additional columns, not additional rows.
One approach is multiple LEFT JOIN:
select concat(c.first_name, ' ', c.last_name, ' - ', c.company) as displayname,
c.phone, c.last_name, c.first_name, c.company, c.email,
cvm.value as mobile,
cvf.value as fax,
cvp2.value as second_phone
from contacts c left join
custom_values cvm
on cvm.customized_id = c.id and
cvm.custom_field_id = 4 left join
custom_values cvf
on cvf.customized_id = c.id and
cvf.custom_field_id = 5 left join
custom_values cvp2
on cvp2.customized_id = c.id and
cvp2.custom_field_id = 20;

Related

How to export user data from two different tables using the backoffice sql manager of Prestashop?

I'm not good with sql so i need help exporting my customer's first names, email address, their country and if possible last times they had access to the store.
I managed to get email and first name by using this query :
SELECT firstname, lastname, email, active FROM psdb_customer
From what i understood, since the other data is stored in a different db table, i should use a join to get data from both tables but i haven't been able to figure out how
Any help is welcome
In the past, I helped someone with something similar in the PrestaShop forum. This query should work, just remember that to get a country of a customer they should have at least one address registered and of course I'm using the default db prefix:
SELECT a.`firstname`,
a.`lastname`,
a.`email`,
(SELECT c.`date_add`
FROM `ps_guest` g
LEFT JOIN `ps_connections` c ON c.`id_guest` = g.`id_guest`
WHERE g.`id_customer` = a.`id_customer`
ORDER BY c.`date_add` DESC LIMIT 1) AS `last_activity`,
(SELECT cl.`name`
FROM `ps_address` ad
LEFT JOIN `ps_country_lang` cl ON cl.`id_country` = ad.`id_country`
WHERE ad.`id_customer` = a.`id_customer`
ORDER BY ad.`id_address` DESC LIMIT 1) AS `country_name`
FROM `ps_customer` a
Rolige's answer is what i was looking for.
Here is another query that allows filtering the results by country (using the id_country)
SELECT SQL_CALC_FOUND_ROWS a.`id_address`,
a.firstname as firstname,
a.lastname as lastname,
cl.id_country as country, cl.`name` as country
FROM `ps_address` a
LEFT JOIN `ps_country_lang` cl ON (cl.`id_country` = a.`id_country`
AND cl.`id_lang` = 1)
LEFT JOIN `ps_customer` c ON a.id_customer = c.id_customer
WHERE 1 AND a.id_customer != 0
AND c.id_shop IN (1)
AND a.`deleted` = 0
AND cl.`id_country` = '8'
ORDER BY a.`id_address` ASC

Why is my join not returning anything?

Involved Entities:
Rental
Id(PK), BorrowerId, BookId, CheckOutWorkerId, CheckOutDate, DueDate, CheckInWorkerId, CheckInDate
Worker
BannerId(PK), FirstName, LastName, Credentials
StudentBorrower
BannerId(PK), FirstName, LastName, BorrowerStatus
Book
Barcode(PK), Title, Author
So I am having issues trying to join two tables together. The rental entity could have two different workers in the table. So I tried this and it yielded an empty table when there should be well over 30 different rows. Any ideas?
SELECT Rental.Id, Book.Title AS BookRented,
CONCAT(StudentBorrower.FirstName, ' ', StudentBorrower.LastName) AS
RentedBy, Rental.CheckOutDate, CONCAT(w1.FirstName, ' ', w1.LastName) AS CheckedOutBy,
Rental.DueDate, Rental.CheckInDate, CONCAT(w2.FirstName, ' ', w2.LastName AS CheckedInBy
FROM Rental
JOIN Book
ON Book.Barcode = Rental.BookId
JOIN StudentBorrower
ON StudentBorrower.BannerId = Rental.BorrowerId
JOIN Worker w1
ON w1.BannerId = Rental.CheckOutWorkerId
JOIN Worker w2
ON w2.BannerId = Rental.CheckInWorkerId
ORDER BY Rental.Id ASC

How to consolidate in a query?

I need some help writing a query to consolidate names into a list that are associated with a foreign key. Here's my current query,
select distinct concat(c_first, ' ', c_last) as name, pmt_no
from disbursements d
left join contacts c on c.c_no = d.b_no
where d.ba_no = 1
My result set looks like this
Louis Vaz, 586014
Antionette An, 690682
Brian Cald, 690682
Mark Brian, 3233902
My desired outcome is
Louis Vaz, 586014
Antionette An - Brian Cald, 690682
Mark Brian, 3233902
Please note that both the people with pmt_no 690682 are now joined together with a '-' separating them.
You can use the GROUP_CONCAT() function to achieve what you want:
select group_concat(distinct concat(c_first, ' ', c_last) SEPARATOR ' - ') as name, pmt_no
from disbursements d
left join contacts c on c.c_no = d.b_no
where d.ba_no = 1
group by pmt_no
I think you want group_concat() along with a group_by:
select group_concat(c_first, ' ', c_last separator ' - ') as names,
pmt_no
from disbursements d left join
contacts c
on c.c_no = d.b_no
where d.ba_no = 1
group by pmt_no;

Multiple answers on one line

I have the following tables:
matters(matterid, mattername, refno)
mattersjuncstaff(junked, matterid, staffid, lead)
staff(staffid, staffname)
A matter may have a number of staff associated with it and a number of those staff will be marked as ‘leads’ i.e. they will have a ‘Y’ in the ‘lead’ field.
I wish to show a table that has a list of matters, the matter name and ref no and those staff marked as leads, ideally in a single row. So it would look something like:
reference | mattername | Lead Staff |
ABC1 | matter abc & Co | Fred Smith, Jane Doe, Naomi Watts |
etc
I am using the code below but this only displays one person with the lead field marked Y.
SELECT refno, mattername, matters.matterid, staffname
FROM matters
INNER JOIN matterjuncstaff
USING (matterid)
Inner join staff
using (staffid)
Inner join matterjuncactions
On matterjuncactions.matterid = matters.matterid
WHERE lead = 'Y'
GROUP BY matters.matterid, nickname
Can anyone tell me how I can I get round this?
You want to concatenate values from a join and represent that as a field in the result set. GROUP_CONCAT function is suited for such queries:
SELECT m.matterid, m.refno, m.mattername, GROUP_CONCAT(s.staffname) AS LeadStaff
FROM matters m
LEFT JOIN matterjuncstaff mjs ON mjs.matterid = m.matterid AND lead = 'Y'
LEFT JOIN staff s ON s.staffid = mjs.staffid
GROUP BY m.matterid, m.refno, m.mattername
The join changed to LEFT and lead = 'Y' moved there, otherwise you will lose matters with no lead staffs.
Use INNER JOIN if you only want matters having some lead staff.
I have removed matterjuncactions as you did not give its info.
Use the GROUP_CONCAT() function in mysql to concatenate values from a query into a single string.
For example you could select a row for each matter and append a column with all the concatenated lead staff names as follows:
SELECT m.refno,
m.mattername,
(Select GROUP_CONCAT(distinct staffname SEPARATOR ', ')
from mattersjuncstaff js
join staff s
on s.staffid = js.staffid
where js.lead = 'Y'
and js.matterid = m.matterid) as LeadStaffMembers
FROM matters m
Update
Here is the same example, but with an added column showing staff members that are not the lead.
SELECT m.refno,
m.mattername,
(Select GROUP_CONCAT(distinct staffname SEPARATOR ', ')
from mattersjuncstaff js
join staff s
on s.staffid = js.staffid
where js.lead = 'Y'
and js.matterid = m.matterid) as LeadStaffMembers,
(Select GROUP_CONCAT(distinct staffname SEPARATOR ', ')
from mattersjuncstaff js
join staff s
on s.staffid = js.staffid
where js.lead <> 'Y'
and js.matterid = m.matterid) as NonLeadStaffMembers
FROM matters m

SQL combining multiple columns from same table while querying multiple tables

I have got three tables that looks as follows.
usedetails [ID,first_name,last_name,telephone,email]
address [ID,streetnumber,streetname,town,county,postcode,userdetailsID]
BOOKING [ID,customerID,pickup_address_id,dropoff_address_id,charge,no_of_passenger]
Address table holds two types of address ie pickoff and dropoff. I would like to display each of the two addresses as one string. The following is my query.
query = "SELECT A.streetnumber,
A.streetname,
A.town,
A.postcode
AS pickup_point
AB.streetnumber,
AB.streetname,
AB.town,
AB.postcode
AS dropoff_point
UD.first_name,
UD.last_name,
UD.telephone,
UD.email
FROM userdetails UD
INNER JOIN booking B
ON B.customerID = UD.ID
INNER JOIN address A
ON B.pickup_address_id = A.ID
INNER JOIN address AB
ON AB.drop_off_address_id = A.ID
WHERE UD.ID = A.userdetailsID OR UD.ID = AB.userdetailsID";
Try CONCAT function:
SELECT CONCAT(A.streetnumber,
' ',
A.streetname,
' ',
A.town,
' ',
A.postcode) AS pickup_point, ...
Or CONCAT_WS function to pass separator as the first argument:
SELECT CONCAT_WS(' ',
A.streetnumber,
A.streetname,
A.town,
A.postcode) AS pickup_point, ...