This question already has answers here:
How to include a PHP variable inside a MySQL statement
(5 answers)
Closed 2 years ago.
I have two tables on a forum that I am referencing via a SELECT query. One table is the phpBB_users table, which holds the basic data for a member while the second table, phpbb_profile_fields_data, holds details such as address, email, phone, etc. Both tables use user_id as the key. My form selects the $smode parameter, which lists the various column headings to search for and the $parameter variable, which enters the actual data to search for. The results are displayed in an HTML table.
Here's my code:
$conn = new mysqli('localhost',$user,$pass,$database);
$sql = "SELECT * FROM phpbb_users
INNER JOIN phpbb_profile_fields_data ON phpbb_users.user_id = phpbb_profile_fields_data.user_id
WHERE $smode = $parameter
ORDER BY username";
$result = $conn->query($sql);
If I select group_id (which is in the phpbb_users table) as my $smode variable and enter a given group number as the $parameter variable, I get a nice listing of the members within that group. If I change the $smode variable to pf_user_lastname (which is in the phpbb_profile_fields_data table) and enter a common last name I don't get any results. The same holds true if I use username as the $smode variable (which is in the phpbb_users table). I get no results. The group_id column is an integer while the other two are alphanumeric variables but when I change the $smode to pf_mh_year, which is a 4 digit integer in the phpbb_profile_fields_data table, I still don't get any results. I get no error messages in the error_log because $result->num_rows is zero - except for the first case where the listing displays.
I did echo the $sql and it looked fine. But when I tested it in PHPMyAdmin like you suggested it showed that I needed to place the $parameter value in single quotes. Not sure why it worked without them for the one integer column but not the other but either way, everything works now that the quotes are in place.
Related
This question already has answers here:
Is storing a delimited list in a database column really that bad?
(10 answers)
Closed 4 years ago.
I have an issue with SQL IN query: I'm storing multiple employee IDs in a table, separated with commas for each task. When I try to fetch a task with an IN query, I'm not getting the row which contains the employee IDs.
My query is:
select
t.*,
e.emp_name,
d.department_name
from
task as t
LEFT JOIN employee as e on(e.emp_id=t.assign_to)
LEFT JOIN department as d on(d.depart_id=e.depart_id)
where
t.task_status='PENDING'
AND t.created_by!='31'
AND t.assign_to IN ('31')
order by
t.task_id DESC
The stored value in database
IN doesn't work like that
Example if your data looks like:
ManagerName, ManagerOf
'John', 'Steve,Sarah,Dave'
You can't do:
SELECT * FROM managers WHERE 'sarah' IN ManagerOf
IN is best conceived as an extension of OR:
SELECT * FROM managers WHERE managerof IN ('Sarah','Steve')
--is the same as:
SELECT * FROM managers WHERE
managerof = 'Sarah' OR
managerof = 'Steve'
There would be as many OR clauses as there are items in the IN list.
Hopefully this shows you why the database doesn't return you any results.. Because a value of Steve,Sarah,Dave is not equal to either Sarah or Steve. The database doesn't look at the commas and say "oh, that's a list" - it's just a single string of characters that happens to have a comma character every now and then
There are nasty quick hacks to so-so achieve what you want, using LIKE and string concat but they aren't worthy of an answer, to be honest
You need to change your database structure to include a new table that tracks the task id and the employee(s) id it is/was assigned to. After doing that, you'll be able to use IN on the employee id column as you're expecting to with this query
This question already has answers here:
How can I search within a table of comma-separated values?
(6 answers)
Closed 8 years ago.
For example, when a table has a record column named 'product' that contain value such as: 'Laptop, Desktop, Case'. How can I validate these 3 values that break down with a comma against two PHP variables value with $var1='Laptop' and $var2='Desktop' ? So that this row can be found! However, the two variables could be passed in the order of 'Desktop', 'Laptop' as well. Meanwhile, the column could have pattern of 'Case, Desktop, Laptop'. I wonder if there is a solution in MySQL for this kind of scenario that somehow, pick up each element like PHP could and match them with each var individually.
Without knowing anything about your table structure this is a quick example of what you can do.
SELECT * FROM table WHERE $var1 IN (SELECT product FROM table WHERE something = somethingelse) AND $var2 IN (SELECT product FROM table WHERE something = somethingelse)
As I understood, you want the data to be found, if the column 'product' contains 'Laptop' or 'Desktop'. Write this with the LIKE operator in your query:
"SELECT * FROM table WHERE `product` LIKE '%Desktop%' OR `product` LIKE '%Laptop%'"
If you pass the variables it would be:
"SELECT * FROM table WHERE `product` LIKE '%$var1%' OR `product` LIKE '%$var2%'"
Make sure to use the % sign before and after the searched string, so that it will match even if the keyword is anwhere inside the product content.
I have 2 tables, a users table and a trade table.
Which look like:
The structure of my code right now is:
<?php
$history = mysqli_query($con, "SELECT * FROM .......");
while($row = mysqli_fetch_array($history)) {
echo("The sentence");
} ?>
Problem I'm facing is that I'm trying to echo the user_name which in one case has to be the receiver and other the person giving it.
Pro tip: Never use SELECT * in software unless you know exactly why you are doing so. In your case it is harmful.
I'm assuming your query is really against the user and trade tables you mentioned in your question.
First, recast your query using 21st century SQL, as follows:
SELECT *
FROM trade AS t
JOIN user AS s ON s.user_id = t.user_id_sender
WHERE s.facebook_id = $fbid
Second, use this to retrieve your user's names and the item id traded.
SELECT s.user_name AS sender,
r.user_name AS receiver,
t.trade_id AS item_id
FROM trade AS t
JOIN user AS s ON s.user_id = t.user_id_sender
JOIN user AS r ON r.user_id = t.user_id_receiver
WHERE s.facebook_id = $fbid
See how we JOIN the user table twice, with two different aliases s (for sender) and r (for receiver)? That's the trick to fetching both names from IDs.
See how we employ the aliases sender and receiver to disambiguate the two user_name columns in the result set?
Now, when you use the php fetch_array function, you'll end up with these elements in the array.
$history['sender']
$history['receiver']
$history['item_id']
The array index strings correspond to the alias names you specified in your SELECT clause in your query.
So, one reason to avoid SELECT * is that you can get more than one column with the same name, and that means fetch_array will eliminate those duplicates and so it will lose useful information from your result set.
i have a table called site, which records the name of some sites, now the table can have a hundred rows called site.com, and/or site.net, site.me....
now what i need is to get only the unique names, like even if there is 1000 row but only 5 types of sites names exist i need to get those site names.
so far, ive tried without success this
<?php
//mysql goes here
$query = mysql_query(" SELECT * FROM SITES ");
while ($row = mysql_fetch_array($query)){
echo array_diff($row, NULL);
} ?>
nothing shows except argument error.
Use the distinct key word.
SELECT DISTINCT name FROM SITES
This question already has answers here:
How to resolve ambiguous column names when retrieving results?
(11 answers)
Closed 2 years ago.
I have fields that have the same name in different tables that I'm joining. Such as ticket.status, user.status and transaction.status. At the moment the query returns just status.
How can I get the table name in such a way that it stops similar field names from overwriting and so I can tell the difference between the fields.
Simply put:
$data = array($eventId);
$statement = $this->db->prepare("SELECT * FROM ticket, user, transaction
WHERE ticket.eventId = ?
AND ticket.userId = user.userId
AND ticket.transactionId = transaction.transactionId");
$statement->execute($data);
$rows = $statement->fetchAll(PDO::FETCH_ASSOC);
In my research I've found the constant PDO::ATTR_FETCH_TABLE_NAMES that looks like it could help, but I do not know how to implement ( I assume through $statement->setAttribute(); somehow).
I also have concerns that it will not work, as the PHP documentation mentions it is dependent on the driver.
Thanks
Just add new aliases to your select statements
$statement = $this->db->prepare("
SELECT *, ticket.status AS ticket_status, user.status AS user_status, transaction.status AS transaction_status
FROM ticket, user, transaction
WHERE ticket.eventId = ?
AND ticket.userId = user.userId
AND ticket.transactionId = transaction.transactionId
");
Then you can do
$rows[0]['user_status'];
$rows[0]['ticket_status'];
$rows[0]['transaction_status'];
If you are really concern by performance, the quantity of data returned will be greater so instead of adding new aliases you can select every single columns and while you do so put an alias on the status column.
Why not change your to actually join instead:
SELECT
t.status as ticket_status, u.status as user_status, tr.status as trans_status
FROM
ticket as t
inner join user as u on t.userId = u.userId
inner join transaction as tr on t.transactionId = tr.transactionId
where
t.eventId = ?
You don't even need to cast the tables using as something but I find it's neater.
Note, its the casting of the columns that will actually fix this issue, not the join method.
The most obvious comment is "don't do it, that's why aliases exist". But there's still a good underlying question: does MySQL send information about where a result-set column comes from (table, view or calculated)?
Apparently, it does, since the PDOStatement object has an experimental method called getColumnMeta(). I've been testing and it returns an associative array where the table key
contains the source table if column comes from a table or view
is an empty string if the column is calculated
Of course, I'd stick to aliases anyway. Being able to use associative arrays is a killer feature for me.