I want to search a product detail from multiple sql table. I used these queries which do not work. I found many post about this topic but I cannot apply any of them.
Every table has the same structure like (I have 14 table in this category)
id | name | cast | detail | date
I tried:
Method 1:
$result = mysqli_query($db,"SELECT movie.*, audio.*
FROM movie,audio WHERE movie.name='$name' OR audio.name='$name'");
Method 2:
$result = mysqli_query($db,"SELECT *
FROM movie,audio WHERE movie.name='$name' OR audio.name='$name'");
Method 3:
$result = mysqli_query($db,"SELECT * FROM movie,audio WHERE name='$name'");
Note, credit really goes to Giorgos's comment at the top, I just formalized it.
Assuming all tables line up perfectly, and you're just trying to look up something with name in all tables, your third attempt is really close.
The SQL should be
SELECT *
FROM movie
UNION audio
WHERE name='$name'
Just chain UNIONs till you've combined all tables.
Only catch is that the columns will be labeled in the way Movie has them, and if there's any structural differences between the tables, you'll get a lot of weirdness and not the results you want.
In that situation, the trick is to chain UNIONs on SELECTs instead of inside the FROM like so:
SELECT *
FROM movie
WHERE name='$name'
UNION
SELECT *
FROM audio
WHERE name='$name'
If the SQL flavor dislikes that setup, just wrap it in a SELECT * FROM ( ... ).
Side note, directly inserting a variable into your SQL is potentially an SQL Injection risk. If $name is not 100% server-controlled, you may want to investigate switching to parametrized queries instead, potentially with stored procedures.
Or just sanitize the variable. That also works. Injection was blockable that way before parametrization came along.
Related
Okay, basically I have a table that contains statements like:
incident.client_category = 1
incident.client_category = 8
incident.severity = 1
etc.
I would like to use the contents from this table to generate other tables that fulfill the conditions expressed in this one. So I would need to make it something like
SELECT * FROM incident WHERE incident.client_category = 1
But the last part of the where has to come from the first table. Right now what I'm trying to do is something like
SELECT * FROM incident WHERE (SELECT condition FROM condition WHERE id = 1)
id = 1 stands for the condition's id. Right now I only want to work with ONE condition for testing purposes. Is there a way to achieve this? Because if there isn't, I might have to just parse the first query's results through PHP into my incident query.
Table schemas:
Engineering Suggestion - Normalize the DB
Storing a WHERE clause, like id = 10, in a field in a MySQL table, is not a good idea. I recommend taking a look at MySQL Normalization. You shouldn't store id = 10 as a varchar, but rather, you should store something like OtherTableid. This allows you to use indices, to optimize your DB, and to get a ton of other features that you are deprived of by using fields as WHERE clauses.
But sometimes we need a solution asap, and we can't re-engineer everything! So let's take a look at making one...
Solution
Here is a solution that will work even on very old, v. 5.0 versions of MySQL. Set the variable using SET, prepare a statement using PREPARE, and execute it using EXECUTE. Let's set our query into a variable...
SET #query = CONCAT(
"SELECT * FROM incident WHERE ",
(SELECT condition FROM condition WHERE id = 1)
);
I know for a fact that this should work, because the following definitely works for me on my system (which doesn't require building any new tables or schema changes)...
SET #query = CONCAT("SELECT id FROM myTable WHERE id = ", (SELECT MAX(id) FROM myTable));
If I SELECT #query;, I get: SELECT id FROM myTable WHERE id = 1737901. Now, all we need to do is run this query!
PREPARE stmt1 FROM #query;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
Here we use a prepare to build the query, execute to execute it, and deallocate to be ready for the next prepared statement. On my own example above, which can be tested by anyone without DB schema changes, I got good, positive results: EXECUTE stmt1; gives me...
| id | 1737901 | .
here is one way to achieve your goal by using what is called dynamic sql, be ware that this works only select from condition table returns only one record.
declare #SQLSTRING varchar(4000)
, #condition VARCHAR(500) -- change the size to whatever condition column size is
SELECT #condition = condition
FROM
condition
WHERE
id = 1
SET #SQLSTRING= 'SELECT * FROM incident WHERE ' + #condition
exec sp_executesql(#SQLSTRING)
Since you have also tagged the question with PHP, I would suggest using that. Simply select the string from the condition table and use the result to build up a SQL query (as a string in PHP) including it. Then run the second query. Psudo-code (skipping over what library/framework you re using to call the db):
$query = "select condition from condition where id = :id";
$condition = callDbAndReturnString($query, $id);
$query = "select * from incident where " . $condition;
$result = callDb($query);
However, be very careful. Where and how are you populating the possible values in the condition table? Even how is your user choosing which one to use? You run the risk of opening yourself up to a secondary SQL injection attack if you allow the user to generate values and store them there. Since you are using the value from the condition table as a string, you cannot parametrise the query using it as you (hopefully!) normally would. Depending on the queries you run and the possible values there as conditions, there might also be risk even if you just let them pick from a pre-built list. I would seriously ask myself if this (saving parts of SQL queries as strings in another table) is the best approach. But, if you decide it is, this should work.
My application has a dashboard screen which has many charts showing metrics and results of user activity, sales performance, etc.
These results can be filtered by date, user and many other options. Supposing I've got one query for each chart, what's the best way to apply the same filtering rule in these multiple queries? Whats the best way to replicate the same "where" clause (the same filtering rule) accross many queries?
As example,
SELECT * FROM users WHERE date = '2014-10-03';
SELECT * FROM products WHERE date = '2014-10-03';
Both queries have same rules.
Some suggested to set a variable with this rule and concatenate it to other queries. Something like:
$where = "WHERE date = '2014-10-03'";
$query = "SELECT * FROM users ". $where;
...
$query = "SELECT * FROM products ". $where;
...
But I can't see this as a good pratice.
If it is similar to issue I had in past I guess you need these restricted by many often repetitive WHERE conditions. User, department permission, time, etc.
What worked in my case was making these into string variables and reusing them across queries that produce charts and graphs. Of course, do not insert user data into your dynamic queries. Hope it helps.
Would it not be a better idea to only keep the value dynamic in case tables do not share the same column name for date.
$date = '2014-10-03';
$query = "SELECT * FROM users WHERE `date_added` = $date";
$query = "SELECT * FROM products WHERE `date_purchased` = $date";
Note: use appropriate validation and security checks for using user input data in sql.
I think you should look into using Prepared Statements. Similar to bind variables in Oracle.
The query only needs to be parsed (or prepared) once, but can be executed multiple times with the same or different parameters
Good explanation here: http://docs.php.net/pdo.prepared-statements
Prevents SQL injection attacks as well
I was running a site I purchased that I thought was fairly unhackable. However, after having an attack, I found it was not. He informed me of the vulnerability, however my question is what user input could have been done to get all the users usernames like he did? Here is the code...
$un=$_GET['username'];
$q=$db->query("SELECT * FROM users WHERE login_name='$un' OR username='$un'");
I realize that this is highley hackable. Therefore, I changed the site over to prepared statements to prevent this from happening again. I just want to know what he could have entered to get all the users usernames.
Someone posted the script on github, you can find it here:
https://github.com/sat312/Mafia-Game-Script/blob/master/checkun.php
' OR 1=1;
In the URL:
/yourScript.php?username=%27%20OR%201%3D1%3B
The idea is that since data is mixed with the command, you can just finish the command with data.
You get $un from the user, so I can type anything I want and it'll get substituted into your query. It's called a SQL Injection attack.
Lets say $un = ' OR 1 = 1;-- then your query becomes:
SELECT * FROM users WHERE login_name='' OR 1 = 1;--' OR username='' OR 1 = 1;--'
What will happen? this gets executed:
SELECT * FROM users WHERE login_name='' OR 1 = 1;
This will return every row in the table.
He may have used the GROUP_CONCAT statement in MySql which basically groups a column in multiple rows into a single row (see Can I concatenate multiple MySQL rows into one field? for more information). He may have terminated the original SQL statement or UNIONED it with his own and added a LIMIT and ORDER BY to ensure his result got returned and commented out the remained of the original statement.
This is one possibility, but there are probably a few others.
This question already has answers here:
Which is faster/best? SELECT * or SELECT column1, colum2, column3, etc
(49 answers)
select * vs select column
(12 answers)
Closed 8 years ago.
Lets say I have a table named users with the fields id, name, username, and password. When i write the query for getting all of the fields, is it better to write it this way
$sql = mysqli_query($con,"SELECT * FROM users LIMIT 50");
or this way:
$sql = mysqli_query($con,"SELECT id, name, username, password FROM users LIMIT 50");
for this code:
while($me = mysqli_fetch_array($sql)){
$id = $me['id'];
$name = $me['name'];
$user = $me['username'];
$pass = $me['password'];
}
Is one better then the other. Is one more finely tuned then the other. Or are they both the exact same performance wise
There is no difference in performance at all. I recommend being explicit about the columns that you want to select in production code, however. If you add a column to the table it could have an effect on the query. It's also clearer to anyone maintaining the code what the query is doing and what values are needed.
In point of fact, using SELECT * is less efficient because MySQL will have to look up the column names and it's less memory efficient because the constructs that PHP creates will have more values than are used (possibly) which costs more memory. However, I think this is negligible enough for my "no difference" comment to stand.
I dont know about performance, but when doing joins this can get you into trouble if you have the same column in more than one table. In this case you need to manually alias which will generally require listing all the columns anyhow. Given that i prefer to remain consitent, and as Explosion Pills mentions its easier to tell whats going on/maintain, than using *.
Never use * to return all columns in a table–it’s lazy. You should only extract the data you need. Even if you require every field, your tables will inevitably change.
Fore more detail see this
I was recently trying to do a project*, which caused me to ask this question. Although since then I've found an alternative solution, I am still curious if what I envisioned doing is, in any way, possible.
Essentially, I am wondering if there is anyway to perform a MySQL query on a MySQL query result in php. For example:
$result = mysql_query("SELECT * FROM foo WHERE bar=".$barValue);
AND THEN, be able to perform multiple queries on $result:
$newResult = mysql_query("SELECT * FROM $result WHERE otherBar=".$barValue);
OR
$otherNewResult = mysql_query("SELECT * FROM $result WHERE otherOtherBar=".$barValue." ORDER BY foobar ASC");
AND so on and so forth...
I realize that I could append the original query with my new WHERE statements and ORDER BYs, but that causes my to query the database unnecessarily and it prevents me from writing more objected oriented code (because I can't pass around a result to be queried, but rather have to requery the database in every function...)
Any advice, pieces of code, frameworks, or ramblings appreciated.
*BTW, my project was having to query a large database of people for people born in certain age groups and then query those age groups for different demographics.
Edit
No, writing a custom function to query the database is not worth the object-orientation (and modifiability) it would give me
You could do a nested query in the same SQL query and keep PHP out of it:
'SELECT * FROM (SELECT * FROM foo WHERE bar="something") AS q1 WHERE q1.bar2 = "something else"'
The question has already been answered. However following explanation will help someone who might be interested in knowing the details of it.
What are Nested query / subquery:
Subqueries are also known as nested queries. A subquery is a SELECT statement within another statement. MySQL supports all SQL standards and additionally provides MySQL specific features.
Why should I use Subquery:
Subquery is structured and it is possible to isolate each parts of statement
Subquery is more readable that complex joins and unions
Subquery provides alternative means to perform action which otherwise would require complex joins and unions
What Subquery returns:
A subquery can return a single value, a single row, a single column, or a table. These are called scalar, column, row, and table subqueries.
Reference: http://dev.mysql.com/doc/refman/5.7/en/subqueries.html
http://www.w3resource.com/sql/subqueries/nested-subqueries.php