Getting multidimensional array from right table results - mysql

I have two tables. The first one is customer information and the second is phone numbers.
So in the first table I would have:
ID Name
1 John
2 jill
In the second table I would have:
ID phone ext notes customerID
1 687-5309 20 Primary 1
2 687-5310 55 John's cell phone 1
3 687-5311 18 Note! Emergency Only! 1
4 235-1189 2
5 235-2324 24 title:owner 2
When I query it I would like it give me a multidimensional result from the right table. So the result would be:
[ID]=>1
[Name]=>John
[phoneList]=>[
[
[ID]=>1 , [phone]=>687-5309 , [ext]=>20 , [notes]=>Primary ],
[ID]=>2 , [phone]=>687-5310] , [ext]=>55 , [notes]=>John's cell phone ],
[ID]=>3 , [phone]=>687-5311] , [ext]=>18 , [notes]=>Note! Emergency Only! ],
]
]
So far this is as far as I can get:
SELECT *
FROM customer_info
LEFT JOIN (
SELECT *
FROM phone_numbers
) WHERE ID=1
I'm not even sure if this is possible. But it feels like it should be.

Without grouping on the customer_info it would just be a simple LEFT JOIN.
SELECT cust.*, phone.ID AS phone_id, phone.phone, phone.ext, phone.notes
FROM customer_info AS cust
LEFT JOIN phone_numbers AS phone ON phone.customerID = cust.ID
WHERE cust.ID = 1;
But if you want one record per customer_info ID?
Then you could also GROUP BY the customer_info and then use GROUP_CONCAT to get 1 string with the phone id's and the phone numbers.
SELECT cust.ID, cust.Name,
group_concat(concat(phone.ID,':',concat_ws(',', phone.phone, ifnull(phone.ext,''), phone.notes)) separator ';') AS phoneList
FROM customer_info AS cust
LEFT JOIN phone_numbers AS phone ON phone.customerID = cust.ID
WHERE cust.ID = 1
GROUP BY cust.ID, cust.Name;
And if the JSON_OBJECT (MariaDB, MySql) function is available in your version, then one could use that.
SELECT cust.ID, cust.Name,
group_concat(JSON_OBJECT('id', phone.ID, 'phone', phone.phone, 'ext', phone.ext, 'notes', phone.notes)) AS phoneList
FROM customer_info AS cust
LEFT JOIN phone_numbers AS phone ON phone.customerID = cust.ID
WHERE cust.ID = 1
GROUP BY cust.ID, cust.Name;
Test on db<>fiddle here

Related

Join two rows into one in mysql

Hello i´m apologize but i cant resolve this issue... im beginner and dont know how to do... i have code
SELECT a.firstname, a.surname, b.contact
FROM crm_client a
JOIN crm_client_contact b ON ( a.id = b.id_client )
WHERE id_iz = '98'
which results me
name1 surname1 email1
name1 surname1 phonenumber1
name2 surname2 email2
name2 surname2 phonenumber2
i would like have phonenumber in next column
email and phonenumber has id_contact column... where 1 is for phone and 2 for email...
Cany somebody help me?
If this is always the format -> only phone number + email per name , then you can simply do this:
SELECT a.firstname, a.surname, MAX(b.contact) as email, MIN(b.contact) as phone_number
FROM crm_client a
JOIN crm_client_contact b ON ( a.id = b.id_client )
WHERE id_iz = '98'
GROUP BY a.firstname,a.surname
This should work because numbers are located lower on the ASCI table then letters, therefore - MIN will select the phone number, and MAX will select the email address.
Note that if it's possible for only 1 value to exists, both column will contain it.
Another approach with group_concat & string function
select a.`firstname`, a.`surname`,
substring_index(group_concat(b.`contact`),',',1) as email,
substring_index(group_concat(b.`contact`),',',-1) as phone
from crm_client a
join crm_client_contact b ON ( a.id = b.id_client )
where id_iz = '98'
group by a.`firstname`, a.`surname`

How to get records from two tables with multiple where conditions

I have a two tables one is Userregistration and second is user_verificationcode from which i have to get only those record whose email and mobile status are 1.Below are my table structure
Userregistration table
........................................
id fullname mobile_no email
.........................................
5 varun 12344567 abc#gmail
6 nitin 12345678 def#gmail
user_verificationcode
.............................................
id user_id codetype status
............................................
1 5 email 0
2 5 mobile 1
3 6 email 1
4 6 mobile 1
I want this kind of output
........................................
id fullname mobile_no email
.........................................
6 nitin 12345678 def#gmail
For this i have used below query but its not working i am not getting how to achieve this.
SELECT * FROM Userregistration
INNER JOIN user_verificationcode ON Userregistration.`id`=user_verificationcode.`user_id`
where user_verificationcode.`codetype`='email'
and user_verificationcode.`status`='1'
and user_verificationcode.`codetype`='mobile'
and user_verificationcode.`status`='1'
SELECT r.*
FROM Userregistration r
INNER JOIN user_verificationcode ve ON r.id = ve.user_id
and ve.codetype = 'email'
and ve.status = 1
INNER JOIN user_verificationcode vm ON r.id = vm.user_id
and vm.codetype = 'mobile'
and vm.status = 1
or
SELECT *
FROM Userregistration
where id in
(
select user_id
from user_verificationcode
group by user_id
having sum(codetype = 'email' and status = 1) > 0
and sum(codetype = 'mobile' and status = 1) > 0
)
You probably want to return only Userregistration fields, since you already know the info contained in user_verificationcode table. In this case you can use the following query:
SELECT t1.*
FROM Userregistration AS t1
JOIN (
SELECT user_id
FROM user_verificationcode
WHERE codetype IN ('mobile', 'email')
GROUP BY user_id
HAVING COUNT(DISTINCT codetype) = 2 AND SUM(status <> 1) = 0
) AS t2 ON t1.id = t2.user_id
You may would like to do something like this
SELECT Userregistration.id, Userregistration.fullName, Userregistration.mobile_no,
Userregistration.email FROM Userregistration
INNER JOIN user_verificationcode
ON Userregistration.id=user_verificationcode.user_id
WHERE user_verificationcode.codetype='email' AND user_verificationcode.status = 1
SELECT Userregistration.id,
Userregistration.fullName,
Userregistration.mobile_no,
Userregistration.email
FROM Userregistration
INNER JOIN user_verificationcode ON
Userregistration.id=user_verificationcode.user_id AND
user_verificationcode.status=1
WHERE user_verificationcode.codetype='email' AND
user_verificationcode.codetype='mobile'

mysql SELECT EXISTS on multiple tables

Have tables: person,person_ip
Both tables have pid column as a primary key, in table person there is column state_id, in table person_ip there is column ip.
Want to discover if specified IP address is assigned to person with state_id is not equal to 2. But always got result 1, even if state_id is 0, 1 or 2. Always got 0 only if ip address is not listed at all. What am I doing wrong?
SELECT EXISTS (
SELECT person_ip.PID
FROM person_ip,person
WHERE person.PID=person_ip.PID
AND person.state_id NOT IN (2)
AND person_ip.ip='10.11.12.13'
)
this seems like a simple join.. unless i'm missing something
select person.*
from person
inner join person_ip
on person.pid = person_ip.pid
where person.state_id <> 2
and person_ip.ip_address = '10.0.0.1'
If you want to exclude the ip_address if it has been assigned to any user with state = 2, even if it has also been assigned to a user without state = 2, then try:
select max(i)
from (
select *
from (
select 1 as i
from dual
where not exists (
select 1
from person p
inner join person_ip pi
on p.pid = pi.pid
where p.state_id = 2
and pi.ip_address = '10.0.0.1'
)
) q
union
select 0
) qq
(dual is a system table that can be used as a sort of stub table)
here's a fiddle showing both versions
update after some actual sleep
Okay, so the above query is a little.. out there. Back in the real world, this one is probably more appropriate:
select count(case when p1.state_id = 2 then 1 end)
from person p1
inner join person_ip pi1
on p1.pid = pi1.pid
where pi1.ip_address = '10.0.0.1'
group by pi1.ip_address;
This will return 1 or more if your ip_address has been used by someone with a state_id of 2, and 0 if it has never been used by someone with a state_id of 2.
It will return nothing if the ip has never been used.
this fiddle has all three of the above queries.
SELECT IF(COUNT(*)>0,1,0)
FROM person
INNER JOIN person_ip
ON person.pid = person_ip.pid
AND person_ip.ip_address = '10.0.0.1'
WHERE person.state_id <> 2

MySql Join - How to get all rows besides related? HowTo SUM within a Joined Table?

I have 3 Tables (with prefix "pindex_")
names photos link
id, name id, filename photo_id, name_id
-------- ------------ -----------------
1 , leo 1 , aa.jpg 1 , 1
2 , liz 2 , bb.jpg
3 , ann
So Leo is connected to Photo aa.jpg
Now I would like to get all names that are not connected to aa.jpg.
Result should be: Liz (2), Ann (3).
I have tried with this but it isn't working so far:
select nm.name from pindex_names nm
join pindex_link pl on pl.name_id = nm.id
join pindex_photos pp on pl.photo_id = pp.id
where pl.name_id !='$id'
And my second question is how i can SUM up a Col within a joined table?
For exaple I would like to Count how many names are connected to a certain photo.
Here is one method:
select n.*
from names n
where not exists (select 1
from link l join
photos p
on l.photo_id = p.id
where l.name_id = n.id and
p.filename = 'aa.jpg'
);
SELECT *
FROM pindex_names
WHERE id NOT IN
(
SELECT name_id
FROM pindex_link pl
INNER JOIN pindex_photos pp
ON pl.photo_id = pp.id
WHERE filename='aa.jpg'
)

Multiple rows to one row query

On my database when i do this query:
SELECT *
FROM users u
LEFT JOIN usersToStrategy uts on uts.userID = u.userID
LEFT JOIN strategy s on uts.stratID = s.stratID
I get the following results:
userID username fName utsID userID stratID stratID stratName
1 nlubin Neal 66 1 4 4 s3
1 nlubin Neal 65 1 3 3 s5
1 nlubin Neal 64 1 2 2 s2
1 nlubin Neal 63 1 1 1 s1
How do I structure my query that instead of getting those four rows (for only one user) I get one row for the user with all of the user's strats in one cell in the row like this:
userID username fName stratNames
1 nlubin Neal s3, s5, s2, s1
I can give you as much information that I can within reason to help with the question.
I think you are looking for GROUP_CONCAT
SELECT userID, username, fName, GROUP_CONCAT(stratNames SEPARATOR ', ') AS strats
FROM users u
LEFT JOIN usersToStrategy uts on uts.userID = u.userID
LEFT JOIN strategy s on uts.stratID = s.stratID
GROUP BY userID, username, fName
You use GROUP_CONCAT.
Use GROUP_CONCAT like this
SELECT userID,
username,
fName,
GROUP_CONCAT(stratNames)
FROM users u
LEFT JOIN usersToStrategy uts on uts.userID = u.userID
LEFT JOIN strategy s on uts.stratID = s.stratID
GROUP BY username;