How can I split the value of a column per comma? - php

I have a table like this:
-- mytable
+----+------------+
| id | value |
+----+------------+
| 1 | one,ten |
| 2 | nine,two |
| 3 | five, one |
+----+------------+
The value of value column is always made of two parts which are combined with ,. Now I want to select them in two separated column like this:
-- expected result:
+----+-------+------+
| id | val1 | val2 |
+----+-------+------+
| 1 | one | ten |
| 2 | nine | two |
| 3 | five | one |
+----+-------+------+
How can I do that?
I can do that by PHP like this:
-- query
SELECT id, value FROM mytable
-- then
$vals = explode(",", $rows['value']);
foreach($vals as $val){
//do stuff
}
But I want to know is that possible to I do that in mysql?

For this you can use the function INSTR() to find the position of the comma and then use LEFT() and RIGHT() to split these into the two columns you need, as below:
SELECT id
,LEFT(value,INSTR(value,',')-1) AS val1
,RIGHT(value,CHAR_LENGTH(value)-INSTR(value,',')-1) AS val2
FROM mytable

It would be done by using SUBSTRING_INDEX(string,delimiter,count) like this:
SELECT id,
SUBSTRING_INDEX(value,',', 1) as val1,
SUBSTRING_INDEX(value,',', -1) as val2
FROM mytable

Related

php get records from mysql only when dosent have duplicated value

mysql like that
=======================
| id | name |
| 1 | jhon |
| 2 | sarah |
| 3 | suzan |
| 4 | jhon |
| 5 | ahmed |
=======================
my expected result is
sarah
suszan
ahmed
want to remove jhon or any value name are duplicated
i tried to use
SELECT * FROM table WHERE id={$id} GROUP BY name
but it's only displaying the duplicated values
Use HAVING
SELECT `name` FROM `table` GROUP BY `name` HAVING COUNT(`name`) = 1
To get unique values, you can use below :
// This will return unique values
SELECT DISTINCT `name` FROM `table`;

Sum multiple fields in 1 table

Hi I would like to sum my 4 columns in my table.
but I get error he SUM function requires 1 argument(s)
itemcost table
+------+------+------+------+------+
| id | col1 | col2 | col3 | col4 |
+======+======+======+======+======+
| 0002 | 5 | 5 | 5 | 5 |
+------+------+------+------+------+
| | | | | |
+------+------+------+------+------+
| | | | | |
+------+------+------+------+------+
$cost= DB::table('itemcost')
->select(
DB::raw('SUM(col1,col2,col3,col4) as unitprice')
);
Thank you in advance.
To sum just column of every single row, use:
(col1+col2+col3+col4) as unitprice
Or, to sum columns with rows, use:
(SUM(col1)+SUM(col2)+SUM(col3)+SUM(col4)) as unitprice
By the way, here is an article with examples
You could add columns with + sign,
Try like bellow:
$cost= DB::table('itemcost')
->select(
DB::raw('SUM(col1+col2+col3+col4) as unitprice')
);

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

In MySQL, how do I select only rows with certain values for a given column?

Let's say I have this table:
|user_id | first_name | last_name |
----------------------------------|
| 0 | joe | smith |
| 1 | bob | jones |
| 2 | joe | black |
| 3 | mary | jeane |
| 4 | peter | parker |
How would I go about selecting the contents of the rows which correspond to the user_id's 1, 2 and 3? I want to use these rows later to display their contents in a list to the user.
Try this:
select user_id,first_name,last_name
from your_table_name
where user_id in (1,2,3);
Replace your_table_name with the actual table name.
Place the comma separated column names that you want as output right after select keyword.
in clause is used to select between multiple values.
So in your case, query would look some how like this:
select user_id, first_name, last_name
from table_name
where user_id in (1,2,3);

Delimited foreign ID's in a mysql field

Preface: Yes i realize this is bad design, but i can't change this.
Question
I have a customers table, and within that a field 'products'. Here is an example of what is in a sample customers products field:
36;40;362
Each of those numbers reference a record from the products table. I'm trying to do a
(SELECT group_concat(productName) from products where productID=???)
but am having trouble with the delimiters. I know how to remove the semi colons, and have tried 'where INSTR' or IN but am having no luck.
Is the best approach to return the whole field to PHP and then explode / parse there?
You can use FIND_IN_SET function in MySQL.
You just need to replace semicolons with a comma and the use it in your query:
SELECT group_concat(productName)
FROM products
WHERE FIND_IN_SET(productID, ???) > 0
Just remember that ??? should be comma-separated!
Like you said, this isn't the way to do it. But since it's an imperfect world:
Assuming a database structure like so:
+-PRODUCTS---------+ +-CUSTOMERS---------+------------+
| ID | productName | | ID | customerName | productIDs |
+----+-------------+ +----+--------------+------------+
| 1 | Foo | | 1 | Alice | 1;2 |
+----+-------------+ +----+--------------+------------+
| 2 | Bar | | 2 | Bob | 2;3 |
+----+-------------+ +----+--------------+------------+
| 3 | Baz | | 3 | Charlie | |
+----+-------------+ +----+--------------+------------+
Then a query like this:
SELECT customers.*,
GROUP_CONCAT(products.id) AS ids,
GROUP_CONCAT(productName) AS names
FROM customers
LEFT JOIN products
ON FIND_IN_SET(products.id, REPLACE(productIDs, ";", ","))
GROUP BY customers.id
Would return:
+-RESULT------------+------------+-----+---------+
| ID | customerName | productIDs | ids | names |
+----+--------------+------------+-----+---------+
| 1 | Alice | 1;2 | 1,2 | Foo,Bar |
+----+--------------+------------+-----+---------+
| 2 | Bob | 2;3 | 1,2 | Bar,Baz |
+----+--------------+------------+-----+---------+
| 3 | Charlie | | 1,2 | NULL |
+----+--------------+------------+-----+---------+
FIND_IN_SET( search_value, comma_separated_list ) searches for the value in the given comma separated string. So, you need to replace the semicolons with commas, which is obviously what REPLACE() does. The return value of this function is the position where it found the first match, so for example:
SELECT FIND_IN_SET(3, '1,3,5') = 2
SELECT FIND_IN_SET(5, '1,3,5') = 3
SELECT FIND_IN_SET(7, '1,3,5') = NULL

Categories