Join two rows into one in mysql - 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`

Related

Getting multidimensional array from right table results

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

Can IFNULL() return a string where the column value is int, using MySQL?

My query
select cname, count(screening_occapancy.idclient) as 'Count'
from client, screening_occapancy
where client.client_no = screening_occapancy.idclient
group by cname
returns the following:
Name Count
Name1 2
Name2 3
Name3 6
etc, now I want it the value in 'Count' to be "not found" if the value is null or 0, is that possible? I need something like that in my results:
Name Count
Name1 2
Name2 3
Name3 "Not found"
Select cname ,
case when Count is null or count =0 then 'Not found'
else Count end as count
from
(select cname,
count(screening_occapancy.idclient) as 'Count'
from client left join screening_occapancy
on
client.client_no = screening_occapancy.idclient group by cname) t
Write a wrapper query above your query to check count column
Use a left join to get 0 for all not found matches
select c.cname,
count(so.idclient) as 'Count'
from client c
left join screening_occapancy so on c.client_no = so.idclient
group by c.cname
And BTW don't use the legacy implicit join syntax anymore. Use explicit joins.
select cname, IF(count(screening_occapancy.idclient)!=0,count(screening_occapancy.idclient),'NOT FOUND') as 'Count'
from client, screening_occapancy
where client.client_no = screening_occapancy.idclient
group by cname
or if count returns null?
select cname, IFNULL(count(screening_occapancy.idclient),'NOT FOUND') as 'Count'
from client, screening_occapancy
where client.client_no = screening_occapancy.idclient
group by cname

Select two items from a table as two different things

I have two tables: tblOrganisations and tblContacts. I have a query that brings back Organisations. I also want to bring back two contacts of different types (primary=1, alternate=2) linked to an organisation. However, I'm stuck on how to bring back multiple fields, for multiple contacts, from one table as different things.
So far I can get their ReferenceID's as PrimaryID and SecondaryID.
SELECT tblOrganisations.*
, ( SELECT tblContacts.ReferenceID
FROM tblContacts
WHERE tblOrganisations.ReferenceID = tblContacts.tblOrganisations_ReferenceID
AND tblContacts.tblContactTypes_ReferenceID = 1
) AS PrimaryID
, ( SELECT tblContacts.ReferenceID
FROM tblContacts
WHERE tblOrganisations.ReferenceID = tblContacts.tblOrganisations_ReferenceID
AND tblContacts.tblContactTypes_ReferenceID = 2
) AS SecondaryID
FROM tblOrganisations
The above query gets me the organisation, and the ReferenceID's of their contacts from tblContacts as PrimaryID and SecondaryID for the two different types of contact I want. But I want more fields for each contact - FirstName, LastName, EmailAddress etc
I tried stuff like;
SELECT tblOrganisations.*
,
( SELECT tblContacts.ReferenceID AS PrimaryID ,
FirstName AS PrimaryFirstName
FROM tblContacts
WHERE tblOrganisations.ReferenceID = tblContacts.tblOrganisations_ReferenceID
AND tblContacts.tblContactTypes_ReferenceID = 1
)
,
( SELECT tblContacts.ReferenceID AS SecondaryID ,
FirstName AS SecondaryFirstName
FROM tblContacts
WHERE tblOrganisations.ReferenceID = tblContacts.tblOrganisations_ReferenceID
AND tblContacts.tblContactTypes_ReferenceID = 2
)
FROM tblOrganisations
But that doesn't actually bring back anything in PrimaryID, SecondaryID, PrimaryFirstName etc
Thanks for any help or pointers :)
The table with the desired values has to be joined twice.In this case it would be tblcontacts.
SELECT
o.*,
c1.referenceid AS PrimaryID,c1.firstname as primaryfirstname,
c2.referenceid AS SecondaryID,c2.firstname as secondaryfirstname
FROM tblOrganisations o
JOIN tblContacts c1 on o.ReferenceID = c1.tblOrganisations_ReferenceID
JOIN tblContacts c2 on o.ReferenceID = c2.tblOrganisations_ReferenceID
WHERE c1.tblContactTypes_ReferenceID = 1 and c2.tblContactTypes_ReferenceID = 2

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

How to get all records by using 2 independent condition

I have a list of firstname and lastname. I want a generic query which searches a big master table for each individual using first name and last name and produce an ID value for each. In a nut shell I want records for which there was an ID value present.
AGARWAL NEERU
AHMAD ANEES
AHUJA KARUMA
AHUJA SAM
AL-HATTAB EYAD
ALATRASH FIDA
So I basically want to retrieve some result for these input as below.
1221 AGARWAL NEERU
2323 AHMAD ANEES
4432 AHUJA KARUMA
1542 AHUJA SAM
8777 ALATRASH FIDA
The only approach I can think of is using in with where clause on fisrtname and lastname individually. Its not giving what I want because
select b.id,a.firstname, a.lastname from master_table a , ID_table b
where a.firstname in ('NEERU', 'ANEES', 'KARUMA', 'SAM', 'FIDA', 'EYAD')
and a.lastname in ('AGARWAL','AHMAD','AHUJA','ALATRASH')
Now the above query will also give me output for people like below: (You notice people with different first or last name combination than what I want)
3433 AHMAD SAM
You need to test each firstname/lastname combination separately, and combine them with OR. You also need a joining condition between master_table and ID_table
SELECT b.id,a.firstname, a.lastname
FROM master_table a
JOIN ID_table b ON a.id = b.id
WHERE (a.firstname = 'NEERU' AND a.lastname = 'AGARWAL')
OR (a.firstname = 'ANEES' AND a.lastname = 'AHMAD')
OR (a.firstname = 'KARUMA' AND a.lastname = 'AHUJA')
OR (a.firstname = 'SAM' AND a.lastname = 'AHUJA')
OR (a.firstname = 'FIDA' AND a.lastname = 'ALATRASH')
You can simply use 'UNION' condition.
You can have 2 queries with multiple conditions and merge the results using 'UNION'
eg:
SELECT a,b,c FROM table WHERE a IS NULL
UNION
SELECT a,b,c FROM table WHERE b IS NULL