how to get same value from different rows using php - php

I have a database and 1 table.table name is : cranetype they have 4 fields (cf_did,cf_firstname, cf_comment,cf_cranetype) .
database values below.
cf_did cf_firstname cf_comment cf_cranetype
1 Alexy tfhgfnjh 2,3
2 Thomas fdghfgh 11,6,3
3 Thomas cgjkjhl 5,6,11,3
4 Thomasxc cgjkjhl 1,6,9,4
5 Thomaseg fdghgh 11,12,3
6 Thomasm fsgdfgbd 11,6,3
7 Thomabs dgtrty 7,9,11
8 Rdgfghfdg bfdhh 1,3,4
9 Gngfdytyt eertret 1,6,3
10 Dvbgfj hfdhhyrtyr 6,3
11 Hnfhghyt bfgfdhg 11,6,3
12 Adgfdyh dfsdtrst 1
13 Rida gfhgfjgh 3,7,68
I have a select box, they have values (1,2,3,4,...).
If I select value 1 from select box.
I want to check database table(cranetype) field cf_cranetype.
E.g :
$sql= mysql_query("SELECT * FROM `cranetype` WHERE `cf_cranetype`='1'");
while($row=mysql_fetch_array($sql))
{
<?Php echo $row['cf_did'];?>
}
I want output like this:
if cf_cranetype =1.
4,8,9,12. (these are cf_did)
My code is:
$cranetype = $_POST['cranetype'];
$words = explode(',', $cranetype);
if (strlen($cranetype) > 0) {
$Where = '';
foreach ($words as $Item) {
$Where = "cf_cranetype LIKE '%$Item%' AND";
}
$Where = substr($Where, 0, -4);
$list_ul = "(SELECT * FROM cf_directory` WHERE $Where)";
$query = mysql_query($list_ul) or die(mysql_error());
}

A solution is using find_in_set and group_concat:
SELECT GROUP_CONCAT(cf_did) as cf_dids
FROM `cranetype`
WHERE FIND_IN_SET('1', `cf_cranetype`) > 0;
Demo:
create table cranetype(cf_did int, cf_firstname varchar(100), cf_comment varchar(100), cf_cranetype varchar(50));
insert into cranetype values
(4, 'Thomasxc', 'cgjkjhl', '1,6,9,4'),
(7, 'Thomabs', 'dgtrty', '7,9,11'),
(8, 'Rdgfghfdg', 'bfdhh', '1,3,4'),
(9, 'Gngfdytyt', 'eertret', '1,6,3'),
(12, 'Adgfdyh', 'dfsdtrst', '1');
SELECT GROUP_CONCAT(cf_did) as cf_dids
FROM `cranetype`
WHERE FIND_IN_SET('1', `cf_cranetype`) > 0;
Output:
mysql> SELECT GROUP_CONCAT(cf_did) as cf_dids
-> FROM `cranetype`
-> WHERE FIND_IN_SET('1', `cf_cranetype`) > 0;
+----------+
| cf_dids |
+----------+
| 4,8,9,12 |
+----------+
1 row in set (0.00 sec)

use Find_in_set() in mysql.
SELECT * FROM cranetype WHERE FIND_IN_SET ('1',cf_cranetype);

You need to use FIND_IN_SET. Please check link for more explanation.
here your query is
SELECT * FROM cranetype WHERE FIND_IN_SET ('1',cf_cranetype);

Related

php mysql group by

this is my table
row | car_id | car_model | car_features |
1 1 CAR 1 Features 1
2 2 CAR 2 Features 2
3 2 CAR 2 Features 3
and i want to make it like
row | car_id | car_model | car_features |
1 1 CAR 1 Features 1
2 2 CAR 2 Features 2, Features 3
and this is my php mysql script:
<?php
$con = mysql_connect("localhost", "root", "root");
mysql_select_db("car", $con);
$format = mysql_query("SELECT c.* , p.*, d.*,f.* ,e.* FROM bsi_car_master c,bsi_car_type p, bsi_car_vendor d, bsi_selected_features f, bsi_car_features e WHERE c.car_type_id=p.id AND c.car_vendor_id=d.id AND c.car_id = f.car_id AND f.features_id = e.id");
$row = 1;
while($srow = mysql_fetch_array($format))
{
blah blah blah....
}
?>
Use GROUP_CONCAT with GROUP BY. Try this -
SELECT `row`, `car_id`, `car_model`, GROUP_CONCAT(`car_features`, ',')
FROM your_table GROUP BY `car_id`
SELECT car_id,car_model,GROUP_CONCAT(car_features,',')
FROM yourtable
GROUP BY car_id,car_model;
$format = mysql_query("SELECT c.* , p.*, d.*,f.* ,e.*,group_concat(`c.car_features`,',') as `carfeatures` FROM bsi_car_master c,bsi_car_type p, bsi_car_vendor d, bsi_selected_features f, bsi_car_features e WHERE c.car_type_id=p.id AND c.car_vendor_id=d.id AND c.car_id = f.car_id AND f.features_id = e.id group by c.car_id");
Hopefully, it's fairly obvious that I'm no PHP coder, but here's another way to do it, without GROUP_CONCAT()...
<?php
/*
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,car_id INT NOT NULL
,car_model VARCHAR(12) NOT NULL
,car_features VARCHAR(20) NOT NULL
);
INSERT INTO my_table VALUES
(1 ,1 ,'CAR 1','Features 1'),
(2 ,2 ,'CAR 2','Features 2'),
(3 ,2 ,'CAR 2','Features 3');
*/
require('path/to/mysqli/connection/stateme.nts');
$query = "
SELECT id
, car_id
, car_model
, car_features
FROM my_table
ORDER
BY car_model;
";
$result = mysqli_query($db,$query);
$car_id = 0;
while($row = mysqli_fetch_assoc($result)){
if ($car_id== $row['car_id']){
echo " >".$row['car_features']."<br>\n";
} else {
echo $row['car_model']."<br>\n >".$row['car_features']."<br>\n";
$car_id = $row['car_id'];
}
} // end of while loop
/*
Outputs...
CAR 1
>Features 1
CAR 2
>Features 2
>Features 3
*/
?>

PHP/Mysql: 2 selects from same table in one query

This is how my table looks like:
id | name | value
-----------------
1 | user1| 1
2 | user2| 1
3 | user3| 3
4 | user4| 8
5 | user5| 6
6 | user7| 4
7 | user8| 9
8 | user9| 2
What I want to do is to select all the other users, in one query, who's value is user1's value lower than it's value plus 3, higher than it's value minus 3 or equal to it's value.
Something like this:
$result = mysqli_query($con,"SELECT * FROM users WHERE value<'4' OR value>'-2'") or die("Error: ".mysqli_error($con));
while($row = mysqli_fetch_array($result))
{
echo $row['name'].'<br/>';
}
The problem is that users1's value can vary every time the query is run.
Sorry for lame names, but this should work:
NOTE: I named table with your data as "st".
SELECT b.user, a.value as "user1val", b.value as "otheruservalue" FROM st as a
join st as b
on a.user = "user1" and a.user != b.user
where
(b.value > (a.value - 3)) and (b.value < (a.value + 3))
We get unique pairs of user1's value and other user's value by joining same table. After that we just do some simple comparison to filter rows with suitable values.
$user1 = mysql_fetch_assoc(mysql_query("SELECT `value` FROM `users` WHERE id='1'"));
$result = mysql_query("SELECT * FROM `users` WHERE value<'".$user1['value']."+3' OR value>'".$user1['value']."-3'");
Or nested queries :
$result = mysqli_query($con, "select * from `users` where `value` < (select `value` from `users` where `name`='user1')+3 OR `value` > (select `value` from `users` where `name`='user1')-3");

Query to list which string how many occured in a table?

I have an array of strings and a table with text type column. I want to list which string how many occured in specified column of any row in table. Is there a way to do this with one query?
Example;
$strings = array('test', 'sth');
Table;
id | someTextColumn
-------------------
1 | abc tests
2 | sthab
3 | teststh
4 | abcd
5 | sth
Expected result;
str | occurences
-----------------
test | 2
sth | 3
You can do this with a series of like statements.
Here is an example:
select totest.str, count(t.id)
from (select 'test' as str union all
select 'sth'
) totest left outer join
t
on t.someTextColumn like concat('%', totest.str, '%')
group by totest.str
This is not going to be particularly fast if your tables are large. If you have largish tables, you might want to consider full-text indexing.
If the table size isn't too large and the column is properly indexed:
SELECT 'test', COUNT(id)
FROM tableName
WHERE someTextColumn LIKE '%test%'
UNION ALL
SELECT 'sth', COUNT(id)
FROM tableName
WHERE someTextColumn LIKE '%sth%'
$query = "select someTextColumn, count(id) from tableName where "
for($i=0; $i < count($Strings); $i++)
{
if($i != 0)
$query .= " OR ";
$query .= "someTextColumn =" . $string[$i];
}
$query .= " group by someTextColumn";
$result = mysql_query($query);
Try this I hope this will solve ur problem!!

MySql Find multiple rows for each id

I have a table with 3 columns
---QID---TEXT---CID---
I would like to find 20 rows(QID and TEXT) for each distinct CID. I have already prepared string $cid so that I can use WHERE IN statement.
SELECT * FROM questions q1
WHERE cid=(SELECT cid
FROM questions q2
WHERE q2.cid IN ($cids)
GROUP BY q2.cid)
ORDER BY q1.qid LIMIT 20
Thank you!
Simple query:
$query = 'SELECT QID, TEXT FROM yourDb.yourTable WHERE CID = '.$cid;
or, if $cid is an array:
$query = 'SELECT QID, TEXT FROM yourDb.yourTable WHERE CID IN('.implode(',',$cid).')';
To get to the results:
$pdo = new PDO('mysql:host=yourDBServer','login','password');
if (!$stmt = $pdo->query($query))
{
die('query failed');
}
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
For more info on what you can do with the PDO object, refer to the manual
A quick fix (but not a good one) might be:
$q = 'SELECT QID, TEXT FROM yourDB.yourTB WHERE CID = '.$cid.' LIMIT 20';
In the case of CID IN(1,2,3), I'm not sure if there's a strait forward way of doing this. All I can think of is using unions. Mayby this page can help you out with that.
A fugly fix might also be to ORDER BY CID ASC, and insted of using fetchAll(), do this:
$query = 'SELECT CID,QID, TEXT FROM yourDb.yourTable WHERE CID IN('.implode(',',$cid).')';
//execute query, same as above: $stmt holds results
$results = array();
while($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
if (!is_array($results[$row['CID']))
{
$results[$row['CID']] = array();
}
if (count($results[$row['CID']]) < 20)
{
$results[$row['CID']][] = $row;
}
}
This way, the $results array, will have a key for each CID that was found, and that key's value will be an array of up to 20 records...
The problem is in using the = operator and passing a set of values instead of single one. Change your query to the following and try again
SELECT * FROM questions q1
WHERE cid
IN $cids
ORDER BY q1.qid LIMIT 20
The following snippet uses the MySQL variable trick to assign a number for each row per CID. To keep the example simple I've limited the amount of returned rows to 2 per CID.
select cid
, qid
, text
from (
select if(#last_cid = cid, #rn := #rn + 1, #rn := 1) as rn
, (#last_cid := cid)
, cid
, qid
, text
from YourTable yt
cross join
(select #rn := 0, #last_cid := -1) r
) as SubQueryAlias
where rn < 3;
Data setup:
create table YourTable (QID int, TEXT varchar(50), CID int);
insert YourTable values
(1, 'hi', 1),
(1, 'hi', 1),
(2, 'hi', 1),
(2, 'hi', 1),
(3, 'hi', 2),
(4, 'hi', 2),
(4, 'hi', 2),
(5, 'hi', 3);
This returns up to two rows per CID:
+------+------+------+
| cid | qid | text |
+------+------+------+
| 1 | 1 | hi |
| 1 | 1 | hi |
| 2 | 3 | hi |
| 2 | 4 | hi |
| 3 | 5 | hi |
+------+------+------+

MySQL greatest value in row?

I'm using MySQL with PHP. This is like my table: (I'm using 3 values, but there are more)
id | 1 | 2 | 3
---+---+---+----
1 | 3 |12 |-29
2 | 5 |8 |8
3 | 99|7 |NULL
I need to get the greatest value's column name in a certain row. It should get:
id | maxcol
---+-------
1 | 2
2 | 2
3 | 1
Are there any queries that will do this? I've been trying, but I can't get it to work right.
Are you looking for something like the GREATEST function? For example:
SELECT id, GREATEST(col1, col2, col3)
FROM tbl
WHERE ...
Combine it with a CASE statement to get column names:
SELECT id, CASE GREATEST(COALESCE(`1`, -2147483646), COALESCE(`2`, -2147483646), COALESCE(`3`, -2147483646))
WHEN `1` THEN 1
WHEN `2` THEN 2
WHEN `3` THEN 3
ELSE 0
END AS maxcol
FROM tbl
WHERE ...
It's not pretty. You'd do better to follow Bill Karwin's suggestion and normalize, or simply take care of this in PHP.
function findcol($cmp, $arr, $cols=Null) {
if (is_null($cols)) {
$cols = array_keys($arr);
}
$name = array_shift($cols);
foreach ($cols as $col) {
if (call_user_func($cmp, $arr[$name], $arr[$col])) {
$name = $col;
}
}
return $name;
}
function maxcol($arr, $cols=Null) {
return findcol(create_function('$a, $b', 'return $a < $b;'), $arr, $cols);
}
This is a great example of the way normalization helps make query design easier. In First Normal Form, you would create another table so all the values would be in one column, on separate rows.
Since you have used repeating groups to store your values across three columns, you can find the column with the greatest value this way:
SELECT id, IF(col1>col2 AND col1>col3, 'col1', IF(col2>col3, 'col2', 'col3'))
AS column_with_greatest_value
FROM mytable;
The short answer is that there is no simple means to do this via a query. You would need to transpose your data and then determine the largest value that way. So something like:
Select Id, ColumnName, Value
From (
Select '1' As ColumnName, Id, [1] As Value
From Table
Union All
Select '2', Id, [2]
From Table
Union All
Select '3', Id, [3]
From Table
) As Z
Where Exists(
Select 1
From (
Select '1' As ColumnName, Id, [1] As Value
From Table
Union All
Select '2', Id, [2]
From Table
Union All
Select '3', Id, [3]
From Table
) As Z2
Where Z2.Id = Z.Id
Group By Z2.Id
Having Max(Z2.Value) = Z.Value
)
Order By Id
This solution depends on a fixed set of columns where you basically name the columns in the UNION ALL queries. In addition, if you have two columns with identical values for the same Id, you will get duplicate rows.
This query will return the max value regardless of NULLs
SELECT MAX(value)
FROM
(SELECT 1 column_no, col1 value
FROM anotherunamedtable
UNION ALL
SELECT 2, col2
FROM anotherunamedtable
UNION ALL
SELECT 3, col3
FROM anotherunamedtable) t
If you really need the column number then
SELECT id,
(SELECT column_no
FROM
(SELECT 1 column_no, col1 value
FROM anotherunamedtable
WHERE id = t.id
UNION ALL
SELECT 2, col2
FROM anotherunamedtable
WHERE id = t.id
UNION ALL
SELECT 3, col3
FROM anotherunamedtable
WHERE id = t.id) s
ORDER BY max_value DESC
LIMIT 1)) as column_no
FROM anotherunamedtable t
But I think that the last query might perform exceptionally horrible.
(Queries are untested)
In the php side, you could do something like this:
foreach ($rows as $key => $row) {
$bestCol = $best = -99999;
foreach ($row as $col => $value) {
if ($col == 'id') continue; // skip ID column
if ($value > $best) {
$bestcol = $col;
$best = $value;
}
}
$rows[$key]['best'] = $bestCol;
}
Or something similar...
Forests and trees, here's a trivial and fastest solution (providing I didn't fumble); the expression simply looks for the largest column in the row
SELECT id,
CASE COALESCE(col1, -2147483648) >= COALESCE(col2, -2147483648)
WHEN
CASE COALESCE(col2, -2147483648) >= COALESCE(col3, -2147483648)
WHEN true THEN 1
ELSE
CASE COALESCE(col1, -2147483648) >= COALESCE(col3, -2147483648)
WHEN true THEN 1
ELSE 3
END
END
ELSE
CASE COALESCE(col2, -2147483648) >= COALESCE(col3, -2147483648)
WHEN true 2
ELSE 3
END
END
FROM table t
a version with IF() would maybe be more readable, but the above should perform a bit better
To deal with NULLS an INT value with minimum of -2147483648 was assumed, the expression could be rewritten to deal explicitly with nulls but would have to branch into 8 different cases and is left as an exercise for the OP.

Categories