MySQL join on 2 tables - mysql

I need to do a search on 2 simultaneous tables, and I thought that this join would work but its giving me an incorrect syntax error.
$return_arr = array();
$query = mysql_query("SELECT * FROM clients WHERE lastname LIKE '$q%' AND agencyid = '$agencyid'
UNION
SELECT * FROM busclients WHERE busname LIKE '$q%' AND agencyid = '$agencyid'")or die(mysql_error());
if($query) {
while ($result = mysql_fetch_array($query)) {
if(isset($result['busname'])){
$description['id'] = $result['ID'];
$description['value'] = $result['busname'] ;
array_push($return_arr,$description);
}
else
{
$description['id'] = $result['ID'];
$description['value'] = $result['lastname'] . ", " . $result['firstname'] ;
array_push($return_arr,$description);
}
}
}
echo json_encode($return_arr);
Edited with fix suggested below and entire syntax
This is a query from an autocomplete search box. So when someone types in a client or business client name, it uses this query to search the database and then displays the results using jquery.
The fix below works but when I do a search on a business client it is returning []. A client search works fine.

You could use two seperate query's and join them together like so:
SELECT * FROM clients
WHERE lastname LIKE "%agencyid%"
UNION
SELECT * FROM busclients
WHERE busname LIKE "%$agencyid%";

You sql syntax shoul look like this :
SELECT * FROM clients c
inner join
busclients b
on c.agencyid=b.idbus
WHERE (c.lastname and b.busname LIKE '$q%') AND c.agencyid = '$agencyid'
Just to complete the circle make sure you read this article on how to join tables in mysql

Related

Convert SQL query to yii2?

Until now I have been using a SQL query in yii2 which was working fine locally but as soon as I deploy it to the server it shows
I have tried changing it to yii query since its a proper implementation below
$query = $connection->createCommand("SELECT a.name_of_flight, a.time_of_flight, (a.no_of_passenger - b.cnt) as avail, a.no_of_passenger FROM flight_schedule a LEFT JOIN (SELECT flight_time, COUNT(id) AS cnt FROM book_eticket WHERE flight_date='$date' AND company_name = '$comp_name' GROUP BY flight_time) b ON a.id = b.flight_time")->queryAll();
to
$query = (new \yii\db\Query());
$query
->select('a.name_of_flight, a.time_of_flight, (a.no_of_passenger - b.cnt) as avail, a.no_of_passenger')
->from('flight_schedule a')
->leftJoin('flight_time', ('COUNT(id) AS cnt FROM book_eticket'))
->where(array('and', 'flight_date=2016-6-29', 'company_name = Team5'))
->groupBy(['flight_time b','ON a.id = b.flight_time']);
$command = $query->createCommand();
$query = $command->queryAll();
but I get an error:
Can anybody help me find out the problem? Thanks in advance
First screen says about access issues. Second - that operands like date and team is not string. That is wrong. Can you quote them?

How to search exact string using MySql Query which avoids extended values?

My Query looks like
$search_query = db_query("SELECT nd.nid, users.name, nd.type FROM node as nd
LEFT JOIN node_revisions as nd_rev ON nd_rev.nid = nd.nid AND nd_rev.vid = nd.vid
LEFT JOIN users ON nd.uid = users.uid
WHERE nd.status = 1 AND nd_rev.body LIKE LOWER('%node/100%')
AND nd.nid NOT IN(SELECT DISTINCT nid FROM term_node WHERE tid = 293)");
This query actually returns all the matches from node_revisions.body field, Which includes
node/1000, node/1001.... Etc.,
I want to get only the result of exact match where possible like
"node/100"
"node/100/"
"/node/100"
"/node/100/"
'node/100'
'node/100/'
'/node/100'
'/node/100/'
and not like
"node/1006"
"node/10064/"
"/node/1000"
"/node/10001/"
'node/10023'
'node/1005/'
'/node/1001'
'/node/10069/'
This above query returned me result which has string like below..
..a href="/node/1006"
How to avoid this kind of errors? Please help..
Try removing the % after 100 so the search won't consider any digit after 100, like this:
LOWER('%node/100')
Then consider the following Regular Expression
Example:
`nd_rev.body` REGEXP "^/?node/100/?$"
Oh ya... I got an resolution for this.. I redefined my query like below and it gives me result as expected..
$search_query = db_query("SELECT nd.nid, users.name, nd.type FROM node as nd
LEFT JOIN node_revisions as nd_rev ON nd_rev.nid = nd.nid AND nd_rev.vid = nd.vid
LEFT JOIN users ON nd.uid = users.uid
WHERE nd.status = 1 AND nd_rev.body RLIKE '[[:<:]]" . $search_string . "[[:>:]]'
AND nd.nid NOT IN(SELECT DISTINCT nid FROM term_node WHERE tid = 293)");
Look at
nd_rev.body RLIKE '[[:<:]]" . $search_string . "[[:>:]]'
This is what i expected

Database table join displays multiple entries of same rows when I only want one

I am doing a table join on a mysql databse.
I want the results to display just once but it displays each time there is an entry matching the query.
Here is what I have so far:
$descquery = "SELECT streams.name, streams.desc, users.streamnumber FROM streams, users WHERE users.streamnumber = '$_POST[streamnumber]' AND users.streamnumber = streams.name";
$result = mysql_query($descquery) or die(mysql_error());
// Print out the contents of each row into a table
while($row = mysql_fetch_array($result)){
echo $row['name']. " - ". $row['desc'];
echo "<br />";
}
This prints out multiple entries of what I want. Just wondered if theres something im doing wrong?
You have to use the DISTINCT clause, like this:
SELECT DISTINCT streams.name, streams.desc, users.streamnumber FROM streams, users WHERE users.streamnumber = '$_POST[streamnumber]' AND users.streamnumber = streams.name
Try this:
SELECT DISTINCT s.name, s.desc, u.streamnumber
FROM streams s INNER JOIN users u
ON u.streamnumber = '$_POST[streamnumber]'
AND u.streamnumber = s.name
Remember you MUST always sanitize user input before using it in a query to avoid sql-injection.

configuring how to pull data out of 3 tables with mysql

Here is how the the database is layout. I can connect to DB fine.
I had it pullling from database two things but adding a third i can not get it to pull. I just need some help if i could ..
database - mmoore_drupal
table 1
table name = content_type_uprofile
data
vid= 19723
nid =19674
field_name_value = matthew moore
table 2
table name = location_instance
data
lid = 1521
vid = 19723
nid = 19674
table 3
table name = location
data
lid = 1521
street =
city =
country =
latitude =
longitude =
I am trying to pull name and then other info from the other two tables. But mainly i need to have name and other information from location. I thought i had to have the other table to associate the connection. Any help is appreciated.
$query = "SELECT content_type_uprofile.field_name_value,location.street,location.city
FROM location_instance,location,content_type_uprofile
WHERE location_instance.lid = location.lid and location_instance.nid=content_type_uprofile.nid"
$result = mysql_query($query) or die(mysql_error());
// Print out the contents of each row into a table
while($row = mysql_fetch_array($result)){
echo $row['nid']."-".$row['street']. " - ". $row['city'];
echo "<br />";
}
?>
Use this SQL (explicit join syntax):
SELECT
content_type_uprofile.nid,
location.street,
location.city
FROM
content_type_uprofile
INNER JOIN location_instance
ON (content_type_uprofile.nid = location_instance.nid)
INNER JOIN location
ON (location_instance.lid = location.lid)
The SQL that you posted is using implicit join SQL syntax.
I think for some reason, I think the line in your SQL:
WHERE location_instance.lid = location.lid and location_instance.nid=content_type_uprofile.nid
is filtering out all the rows from your result set. I'm not sure because I avoid the implicit syntax.
You were also missing the nid field which your PHP code is looking for in the result set.
As long as your data is correct (i.e. the fields that you are joining on have the right values), the SQL that I posted will work for you.
You ever done something with join's?
select *.locaition,
*.content_type_uprofile
from location_instance li
inner join location l on l.lid = li.lid
inner join content_type_uprofile ctu on ctu.vid = li.vid

Why doesn't this SELECT query return the results I expect?

I need help with a select query, but before asking the question, I will give a short description of how my system works:
My database has a many-to-many relationship:
table product:
prd_cod(pk) //stores the product code ex: 0,1,2
cat_cod(fk)
prd_name //stores the product name, ex: tv, gps, notebook
table description_characteristc:
prd_cod(fk)
id_characteristic(fk)
description //stores the description of the characteristic, ex: sony, 1kg, hj10
table characteristic:
id_characteristic (pk)
name_characteristic //store the name of characteristic, ex: brand, weight, model
I have already made a suggest jQuery (in the index.php), where every word I type calls suggest.php, which makes a select and returns the result into the suggestion box in the index:
<?php
header('Content-type: text/html; charset=UTF-8');
$hostname = 'localhost';
$username = 'root';
$password = '';
$dbname = 'cpd';
mysql_connect($hostname, $username, $password)or die('Erro ao tentar conecta o banco
de dados.');
mysql_select_db( $dbname );
if( isset( $_REQUEST['query'] ) && $_REQUEST['query'] != "" )
{
$q = mysql_real_escape_string( $_REQUEST['query'] );
if( isset( $_REQUEST['identifier'] ) && $_REQUEST['identifier'] == "sugestao")
{
$sql = "SELECT p.prd_name, d.description
FROM product p
INNER JOIN description_characteristc d using (prd_cod)
WHERE '".$q."' like concat(p.prd_name, '%') AND
concat(p.prd_name, ' ', d.description) like concat('".$q."', '%')LIMIT 10";
$r = mysql_query( $sql );
if ( $r )
{
echo '<ul>'."\n";
$cont = 0;
while( $l = mysql_fetch_array( $r ) ){
$p = $l['nome'];
$p = preg_replace('/(' . $q . ')/i', '<span style="font-
weight:bold;">$1</span>',
$l['prd_nome'].' '.$l['descricao'].' '.$l['descricao']);
echo "\t".'<li id="autocomplete_'.$cont.'"
rel="'.$l['prd_nome'].'.'.$l['descricao'].'">'. utf8_encode( $p ) .'</li>'."\n";
$cont++;
}
echo '</ul>';
}
}
}
?>
Here are my questions:
Currently when the user types 't', the select brings nothing, only when the user type 'tv' is bringing the result:
tv led
tv plasm
tv samsumg
I would like that when the user type 't' the select bring me 'tv'.
When you type 'tv plasm' it's bringing the same name_characteristic twice:
ex: tv plasm plasm
Currently my select selects the prd_name and the descriptions of table description_characteristc:
tv led
I would like my select could make a inverse select too, ex: led tv.
I would like that when the results of the select were shown, there could be a cache feature that shows the order of the most sought for the less sought; remembering that prd_name stores only 'tv'.
The help I'm looking for can be in the form of select, as in the form of procedure. Also, I can edit the php file.
You should split and join your search query on PHP side like this:
<?php
$words = preg_split("/[^\\w]+/", $q);
$first = $words[0] + "%";
$all = implode(" ", $words) + "%";
?>
then use the variables $first and $all in this query:
SELECT p.prd_name, d.description
FROM product p
JOIN description d
ON d.prd_cod = p.prd_cod
WHERE p.prd_name LIKE '$first'
AND CONCAT(p.prd_name, ' ', d.description) LIKE '$all'
Create an index on product (prd_name) for this to work fast.
If you want the words matched in any order, you will have to create a FULLTEXT index on your tables (this is only possible in MyISAM):
CREATE FULLTEXT INDEX fx_product_name ON product (prd_name)
CREATE FULLTEXT INDEX fx_description_name ON description (description)
and write a query like this:
SELECT p.prd_name, d.description
FROM (
SELECT prd_cod
FROM product pi
WHERE MATCH(prd_name) AGAINST ('lcd tv' IN BOOLEAN MODE)
UNION
SELECT prd_cod
FROM description di
WHERE MATCH(description) AGAINST ('lcd tv' IN BOOLEAN MODE)
) q
JOIN product p
ON p.prd_cod = q.prd_cod
JOIN description d
ON d.prd_cod= p.prd_cod
WHERE MATCH(p.prd_name, d.description) AGAINST ('+lcd +tv' IN BOOLEAN MODE)
Note the search term syntax change: 'lcd tv' in the inner query and '+lcd +tv' in the outer one.
You may also want to set ##ft_min_word_len to 1 for the shorter words like tv or gps to match.
Since MySQL cannot build a fulltext index from two or more tables at once, it would be more simple if you denormalized you tables and put the prd_name into the description table. This way, you could get rid of the joins and just write:
SELECT prd_name, description
FROM description d
WHERE MATCH(prd_name, description) AGAINST ('+lcd +tv' IN BOOLEAN MODE)
You're using the LIKE clause badly and you don't seem to know what "AND" means. It's important to separate "and" as used in casual speech from "AND" as used in programming. AND in programming means "BOTH MUST BE TRUE". "and" in casual speech can mean "one of these conditions, you know what I mean?"
Also, you shouldn't be building SQL like this, it's an accident waiting to happen. You really should find a way to bind variables into SQL statements. I don't know PHP, so I can't help with that.
First, you should be using this in your WHERE clause p.prd_name LIKE '$q%'. Try this outside PHP -- outside the web -- just as a simple SQL query: SELECT * FROM PRODUCT P WHERE P.PRD_NAME LIKE 'T%'.
Second, you should fix "AND" to be "OR", since you want one condition OR the other condition to be true. If you want for BOTH conditions to be true, hardly anything will match.