Laravel Eloquent GroupBy Name to Create array of ID's - php

I have a table in my Laravel application which I wish to query.
id | company_name | contact |
-----------------------------
1 | Tesco | Name 1 |
2 | Tesco | Name 2 |
3 | Asda | Name 3 |
4 | Tesco | Name 4 |
5 | Asda | Name 5 |
I'm trying to get an array of all unique company names with all ID numbers.
'Tesco' => [1,2,4]
'Asda' => [3,5]
I have tried
$companies = Contact::select('company_name','id')->groupBy('company_name')->get();
However this requests the 'id' to be included in the group by which defeats the purpose. I understand it's asking for this because it's not a SUM or COUNT etc.
The above table may seem unusual and I know I should have a relation to a companies table however this is necessary at this stage.

You could use GROUP_CONCAT()
$companies = Contact::select('company_name', DB::raw('GROUP_CONCAT(id) as ids'))
->groupBy('company_name')
->get();
This would return something like:
company_name | ids
Tesco | 1,2
Edit: if you want the ids in the form an array, you could just map over the collection to convert it:
$companies->map(function($column) {
$column->ids = explode(',', $column->ids);
});
That should do the trick.

Related

Search Array values in comma Separated Column in Laravel

I have two tables (Assessments, Unit_Assigned). In Assessments table I store Multiple Unit Assigned Ids with comma-separated Format like below
id | title | assignedids
-------------------------
2 | NTitl | 15,25,6
-------------------------
3 | Ctitl | 25,6,38
Unit_Assigned Table display below
id | staffid | unit_id | batchid
---------------------------------
15 | 10 | 25 | 31
---------------------------------
38 | 12 | 18 | 42
---------------------------------
I need to get an assessment list based on staff ID (available in Unit_Assigned table)
I got assigned ids list using below query
$assignedunits=Unitassigning::Where('staffid',$staffid)->get()->pluck('id')->toArray();
try to fetch assessment using below query
$stringconverted=implode(",",$assignedunits);
$completedAssessments=Assessments::whereRaw("find_in_set('$stringconverted',assignedids)")->get();

how to merge multiple rows with same id mysql

I'm new posting here but the community have been my best resource on my projects so far.
I'm a dumb/dummy Mysql "wanna be" and I'm in the middle of a project that is making me go mad.
I have a table from wordpress plugin buddypress that pairs meta_key and meta_values in order to create something akin to a taxonomy. My duty is to use these paired values to implement an advanced group search. Here is the original table:
--------------------------------------------
id | group_id | meta_key | meta_value
--------------------------------------------
1 | 1 | time-zone | Kwajalein
2 | 1 | playstyle | hardcore
3 | 1 | recruiting-status | Open
4 | 1 | ilvl | 115
5 | 1 | main-raid | Final Coil of Bahamut
6 | 1 | voicechat | fc.teamspeak3.com
etc....
Using a view I managed to create a more friendly searchable table for begginers :
gid| time-zone| playstyle | main-raid
--------------------------------------------
1 | | |
1 |Kwajalein | |
1 | | hardcore |
1 | | |
1 | | | Final Coil of Bahamut
1 | | |
And here is the view code:
SELECT distinct
group_id AS 'gid',
IF(meta_key='recruiting-status',meta_value,'') AS 'Recruitment',
IF(meta_key='server',meta_value,'') AS 'server',
IF(meta_key='time-zone',meta_value,'') AS 'tzone',
IF(meta_key='main-raid',meta_value,'') AS 'raid',
IF(meta_key='raid-days',meta_value,'') AS 'days',
IF(meta_key='playstyle',meta_value,'') AS 'playstyle',
IF(meta_key='raid-progression',meta_value,'') AS 'progression',
IF(meta_key='raid-time',meta_value,'') AS 'time',
IF(meta_key='tanker-spot',meta_value,'') AS 'tank',
IF(meta_key='healer-spot',meta_value,'') AS 'healer',
IF(meta_key='melee-dps-spot',meta_value,'') AS 'melee',
IF(meta_key='ranged-dps-spot',meta_value,'') AS 'ranged',
IF(meta_key='magic-dps-spot',meta_value,'') AS 'magic',
IF(meta_key='ilvl',meta_value,'') AS 'ilvl',
IF(meta_key='voicechat',meta_value,'') AS 'voice',
IF(meta_key='voicechatpass',meta_value,'') AS 'voicep',
FROM wpstatic_bp_groups_groupmeta
The point is, I need to merge that result (view) so all the group_id=1 or 2 or 3, etc stand in one single row, like this:
gid| time-zone| playstyle | main-raid
--------------------------------------------
1 |Kwajalein | hardcore | Final Coil of Bahamut
2 |SaoPaulo | regular | Second Coil of Bahamut
etc
Can anyone help me there?
Just surround your IFs in a MAX, or another aggregate function that will capture the non-empty strings (e.g., GROUP_CONCAT), and add a GROUP BY group_id add the end. For example,
SELECT
group_id AS gid,
MAX(IF(meta_key='recruiting-status',meta_value,'')) AS 'Recruitment',
MAX(IF(meta_key='server',meta_value,'')) AS 'server',
...
FROM wpstatic_bp_groups_groupmeta
GROUP BY group_id

Return multiple labels for a field with multiple values

I have a function that runs and gets the labels from a lookup table for values stored in a particular table. When there is 1 value it displays correctly. However when there is multiple values it only returns the first one. For example:
Lookup table is
| Tel_No| Tel_type |
--------------------
| 1 | Info |
| 2 | Support |
| 3 | Call |
Main table is
| TelephoneCalls |
------------------
| 1,3 |
| 3 |
| 1,2,3 |
The function I have at the moment which works for matching 1 value is
function getMonitoring($monitoring){
$query = "SELECT Tel_type FROM TelephoneCalls Where Tel_no = '$monitoring'";
$result9 =mysql_query($query) or die(mysql_error());
list($Tel_type) = mysql_fetch_array($result9, MYSQL_NUM);
return $Tel_type;
}
How can I get it to list the values like below
If 1, 3 then display Info, Call
If 3 display Call
If 1, 2, 3 display Info, Support, Call
Thanks for any help!
I guess the comments touched upon it, but you really should change your schema to be more of a many-to-many relationship than using CSV values in the fields. If you can't this query should work:
SELECT telephonecalls, GROUP_CONCAT(tel_type)
FROM lookup_table
LEFT JOIN main_table ON FIND_IN_SET(tel_no , replace(TelephoneCalls,' ', '')) > 0
GROUP BY telephonecalls;
#outputs
+----------------+------------------------+
| telephonecalls | GROUP_CONCAT(tel_type) |
+----------------+------------------------+
| 1,2,3 | Info,Support,Call |
| 1,3 | Info,Call |
| 3 | Call |
+----------------+------------------------+
http://sqlfiddle.com/#!2/194fd/1/0

INSERT statement in joined table

I have 3 table:
tblNames:
| id | firstname | lastname |
+------+---------------+--------------+
| 1 | John | Smith |
tblJosbs (this table accepts multiple checkbox value at the same time):
| id | jobs |
+------+-----------------------+
| 1 | Nurse |
+------+-----------------------+
| 2 | Call Center Agent |
+------+-----------------------+
| 3 | Police |
tblNamesJobs (this table is used to JOIN the other 2 tables):
| id | name_id | jobs_id |
+------+-------------+-------------+
| 1 | 1 | 1 |
+------+-------------+-------------+
| 2 | 1 | 2 |
+------+-------------+-------------+
| 3 | 1 | 3 |
All is fine but can someone show me the INSERT statement for the 3rd table I should use to when I will add new information?
For example add record that John Smith is a Call Center Agent
insert into tblNamesJobs (name_id,jobs_id )
values (
select id from tblNames where
firstname='John'
and lastname='Smith' limit 1
,
select id from tblJosbs where jobs='Call Center Agent' limit 1
);
If you are already depending on tauto increment..you can get the lastinserid, depending on your adapter.
eg. mysql_insert_id
for PDO we can use --PDO::lastInsertId.
so you will have id's of earlier inserted tables, that you can save in the new one.
INSERT INTO tblNamesJobs (name_id, jobs_id) VALUES (XXXX,YYYY)
That is assuming the table's id is auto-incrementing.
It should be noted that both the name_id and jobs_id columns in the "joiner" table should be foreign keys to the respective columns in the other table.
Edit - Valex's answer goes into more detail about what to do if you don't already have the id values.
If possible, I would recommend using some sort of framework that would handle the "joiner" table for you.

count with doctrine

I have two table:
Name
id | name | city_id
1 | aaa | 1
2 | vvv | 2
3 | ddd | 2
4 | sss | 3
5 | dds | 1
etc
City:
id | name
1 | London
2 | NY
3 | Boston
etc
how can i get City and count:
name_city | count
London | 2
NY | 2
Boston | 1
In City table:
$q = $this->createQuery('a')
->leftJoin('a.Name n')
->select('a.name_city as name_city, sum(n.city_id) as sum');
return $q->execute();
but this is wrong.
You should use count() instead of sum(), and plus, you need a group by.
You do not appear to have a FROM clause, the object type is not specified for the a entity.
Also, read the aggregate values section in the documentation.
this post was kinda helpful but I though that I would add a little more details for anyone looking to join 2 tables and with an aggregate count.
e.g. this post (http://stackoverflow.com/questions/7837671/mysql-join-tables-and-count-instances) but in doctrine.
Using the example above the query would be (doctrine 2.0):
$q = $this->em->createQueryBuilder('a')
->select('a.name_city as name_city, count(n.city_id) as sum');
->from('city','a')
->leftJoin('a.Name n')
->groupBy('n.id')
->orderBy('sum')
$query = $qb->getQuery();
echo $qb->getDql(); // if you want to see the dql created
$result = $query->getResult();

Categories