I'm joining data from two SQL queries and I'm wondering if there is a faster way to do this as a single SQL query because there is a lot of looping involved. I've got two queries that look for different string values in the "option_name" field:
$sql01= "SELECT user_id, option_value FROM wp_wlm_user_options WHERE option_name = 'wpm_login_date' ORDER BY user_id";
$sql02 = "SELECT user_id, option_value FROM wp_wlm_user_options WHERE option_name ='stripe_cust_id' ORDER BY user_id ";
Then I create two arrays:
//Process the 1st SQL query data into an Array
$result_array01 = array();
$j = 0;
while($r = mysql_fetch_assoc($result01)) {
if(!empty($r['option_value'])){
//User Id and Last Login
$result_array01[$j]['user_id'] = $r['user_id'];
$result_array01[$j]['last_login'] = $r['option_value'];
$j++;
}
}
//Process the 2nd SQL query data into an Array
$result_array02 = array();
$k = 0;
while($s = mysql_fetch_assoc($result02)) {
if(!empty($s['option_value'])){
//User Id and Stripe Customer Id
$result_array02[$k]['user_id'] = $s['user_id'];
$result_array02[$k]['cust_id'] = $s['option_value'];
$k++;
}
}
And finally, I combine the arrays:
//Combine the SQL query data in single Array
$combined_array = array();
$l = 0;
foreach($result_array01 as $arr01){
// Check type
if (is_array($arr01)) {
//mgc_account_print("hello: " . $arr01['user_id'] . "\r\n");
foreach($result_array02 as $arr02){
// Check type
if (is_array($arr02)) {
//Check if User Id matches
if($arr01['user_id'] == $arr02['user_id']){
//Create Array with User Id, Cust Id and Last Login
$combined_array[$l]['user_id'] = $arr01['user_id'];
$combined_array[$l]['last_login'] = $arr01['last_login'];
$combined_array[$l]['cust_id'] = $arr02['cust_id'];
$l++;
}
}
}
}
}
Why you doing in two different queries?
Use mysql IN('val', 'val2');
$sql01= "SELECT tbl1.user_id, tbl1.option_value FROM wp_wlm_user_options as tbl1 WHERE tbl1.option_name = 'wpm_login_date'
union all
SELECT tbl2.user_id, tbl2.option_value FROM wp_wlm_user_options as tbl2. WHERE tbl2.option_name ='stripe_cust_id' ";
But using OR/AND will your help you in your case , I didnt see at first that you want combined same table. I didnt delete my answer to help you for another solution
Also you should use DISTINCT to avoid multiple records.
SELECT DISTINCT USER_ID, OPTION VALUE FROM TABLE
I have a script i want to search multiple tables how can i do that.
**Also add ORDER BY function in Mysql query **
help is appreciated.
if(isset($_GET["search"]))
{
$condition = '';
//$query = explode(" ", $_GET["search"]);
$query = explode(" ", $_GET["search"]);
foreach($query as $text)
{
$condition .= "title LIKE +'%".mysqli_real_escape_string($connect, $text)."%' OR ";
}
$condition = substr($condition, 0, -4);
$sql_query = "SELECT * FROM countries WHERE " . $condition;
$result = mysqli_query($connect, $sql_query);
if(mysqli_num_rows($result) > 0)
{
while($row = mysqli_fetch_array($result))
{
echo '<tr><td>'.$row["title"].'</td></tr>';
}
}
else
{
echo '<label>Data not Found</label>';
}
}
SELECT * FROM (
(SELECT title FROM countries WHERE title LIKE '%mystring%')
UNION
(SELECT title FROM locations WHERE title LIKE '%mystring%')
) ta
That's the sql, but would need to point out the drawbacks of using union as a search tool.
a) The longer the tables get the longer the search will get, you can add in Limits on each query and then on the union as a whole - but it's not a winner.
b) The table columns have to match up so you'll need perhaps to do myID as ID, then you will need an extra column to say which each is (0=country, 1= location)
c) I guess you are trying to do a site search of sorts, in which case there isn't a relevance in this instance.
Hence I would use something like http://sphinxsearch.com/ bit tricky to get started, but a really quick search engine. If you have a large site. Otherwise look into mysql full text searches which also have relevence and are built in so easier to get started with.
I have two different sql statements. $sql grabs all the items whose title matches a certain search text. $cat_sql grabs all the category_items that are in a certain category. An item has an ID. A category_item has a field called item_id which is a foreign key to IDs in the items table
...
mysqli setup code
...
$title = $_POST["title"];
$cat_id = $_POST["cat_id"];
$cat_sql = "SELECT * FROM category_items WHERE category_id = '".$cat_id."'";
$sql = "SELECT * FROM items where title LIKE '%". $title ."%' Limit 70";
if (!$result_cat = $mysqli->query($cat_sql)) {
// The query failed.
echo "<h2 >ERROR</h2>";
exit;
}
if (!$result = $mysqli->query($sql)) {
// The query failed.
echo "<h2 >ERROR</h2>";
exit;
}
Then I display all items:
while ($item = $result->fetch_assoc()) {
include 'item_card.php';
}
Currently this just displays all items fetched in the $sql query. Is there some way to remove all items from $result that do not have their ID represented as an item_id in $result_cat?
NOTE:
I would strongly prefer not to do just combine both SELECT statements into a table join because the actual $sql and $cat_sql are not nearly as simple as I have represented here. Also, they vary depending on which if statement they are in.
My question is: given $result and $result_cat, can I remove items from $result?
EDIT 1
As suggested by comments I am making an array if item_ids then doing an in_array query. Progress thus far:
$result_cat_ids = [];
while ($cat_item = $result_cat->fetch_assoc()) {
$result_cat_ids[] = $cat_item['item_id'];
}
EDIT 2 Here is the working code following the suggestions in the comments
if (in_array($item['id'], $result_cat_ids)) {
include 'item_card.php';
}
You may also use 'INTERSECT' sql clause.
$sql = "SELECT * FROM items WHERE id IN (SELECT item_id FROM category_items WHERE category_id = '".$cat_id."' INTERSECT SELECT id FROM items where title LIKE '%". $title ."%')";
This way, you can query for items that accomplish both conditions.
Note: I'm not using "limit 70" but you may add it as well.
Hello I would like to query multiple identical tables in my db which has different prefixes and than display the results randomly but somehow I need to track the origin of the item and I couldn't figure out how
I do the query like this because I don't have access to information_schema
$query = "SHOW TABLES FROM mydb WHERE RIGHT( tables_in_mydb, 5 ) = 'table'";
$res = mysql_query($query);
$num = mysql_num_rows($res);
while($row = mysql_fetch_row($res)) {
$numbers = explode('_', $row[0]);
if($num > 0) {
$q = "SELECT `this`, `that`, `something` FROM ".$numbers[0]."_idetinticaltables"; // :)
$r = mysql_query($q);
while($c = mysql_fetch_array($r)) {
/*display the results randomly with an identifier where the come from*/
}
}
}
You could use ORDER BY RAND() to randomly sort it
The following might work:
Get the list of the tables you're interested in. You already do that.
Create a UNION of multiple SELECT statements. Each SELECT statement differs for the table being selected from and you add a column set to the name of the table (so you can identify it later):
(SELECT *, TABLENAME = 'first_name_of_table' FROM first_name_of_table ...)
UNION
(SELECT *, TABLENAME = 'second_name_of_table' FROM second_name_of_table ...)
UNION
...
ORDER BY RAND() LIMIT 10;
Because it is a UNION you can randomize the whole order then. See How can i optimize MySQL's ORDER BY RAND() function? because it is not that trivial to do well, the example above is only to have an ORDER BY and LIMIT clause placed there. With many entries in your tables, it will kill your server.
$aa=array()
while($c = mysql_fetch_array($r))
{
/*display the results randomly with an identifier where the come from*/
$aa[]=$c;
}
echo $aa; // print "Array"
I wonder if it's possible to shorten query depending on some variable value in elegant way.
For example: I have value named $var = 0 and I would like to send a query that looks like this:
$query = "SELECT id, name, quantity FROM products WHERE quantity > 100";
But whan the $var != 1 I'd like to send a query like this:
$query = "SELECT id, name, quantity FROM products WHERE quantity > 100 AND id = '$var'";
So depending on value of $var I want to execute one of queries. They differ only with last expression.
I found two possible solutions but they are not elegant and I dont like them at all.
One is made in php:
if ( $var == 0 ) {
$query_without_second_expression
} else {
$query_with_second_expression
}
Second is made in mysql:
SELECT WHEN '$var' <> 0 THEN id, name, quantity
FROM products WHERE quantity > 100 AND id = '$var' ELSE id, name, quantity
FROM products WHERE quantity > 100 END
but i dont like it - each idea doubles queries in some whay. Can I do something like this?
SELECT id, name, quantity
FROM products WHERE quantity > 100
CASE WHEN $var <> 0 THEN AND id = '$var'
It's much shorter, and adds part of query if needed. Of course real query is much more complicated and shorter statement would be really expected. Anyone has an idea?
If I understand well..
$query = "SELECT id, name, quantity FROM products WHERE quantity > 100";
if ( $var != 0 ) {
$query .= " AND id = '$var'";
}
do you like it?
You could so something like this on the SQL side:
"SELECT id, name, quantity FROM products WHERE quantity > 100 AND (id = '$var' OR '$var' = 0)
But performance could be impacted. I would suggest building the appropriate query on the PHP side.
I'm no PHP developer (it is PHP, right?), but wouldn't it be easiest to build your query from a concatenated string?
Pseudo-code:
$my_query = "SELECT id, name, quantity FROM products WHERE quantity > 100"
if ($var != 1)
$my_query = $my_query + " AND id = '$var'";
end if;
/*go ahead with your query*/
You can do this:
SELECT id, name, quantity
FROM products
WHERE 1 = 1
AND ( $q IS NULL OR quantity > $q)
AND ( $var IS NULL OR id = $var)
If you want only the first condition to run then pass $q = 100 and $var = NULL, therefore the second condition will be ignored. And for the second query pass the $q = 100 and $var = id value and you will got the your second query.
If they only differ in additional where-statements, I would probably still stay in PHP and do the following:
$conditions = array();
$conditions[] = "(quantity > 100)"
if ($var == 0)
$conditions[] = "(id = '$var')";
if (some-other-expression)
$conditions[] = "(myfield = 'foo' OR myfield = 'bar')";
$sql = "
SElECT id, name, quantity
FROM products
WHERE
";
$sql .= $conditions.join(" AND ");
/ Carsten
I would use a ternary for this:
$query = "SELECT id, name, quantity FROM products WHERE quantity > 100" . ( $var != 0 ? " AND id = '$var'" : '' );
I'm an Oracle guy, but could you use the IF() function in your constraints, e.g.:
SELECT id, name, quantity
FROM products
WHERE quantity > 100
AND id = IF('$var'=0,'%','$var');
The '%' is a wildcard that would match anything, effectively ignoring the 2nd expression.
So if you are using the
If or the CASE
Why don't you use them in your sql query.
It would be some like
if ( $var == 0 ) {
$query_without_second_expression
}
else
{
$query_with_second_expression
}
But in you sql query.
DECLARE #var int
if(#var=1)
BEGIN
query 1
END
else
BEGIN
query 2
end
I guess this will solve your problem.
But as a personal advice try to make one query. Even with the variable. We don't believe in changing standard query depending on the conditions.
Still your wish and your desire
Cheers!!
For this particular problem, go with Paper-bat's simple condition append snippet.
However, if you have entirely different where statements, consider appending the appropriate where statement to the query once you know what you want. For instance,
$query = "SELECT id, name, quantity FROM products ";
if ( $var == 0 ) {
$query .= "quantity > 100";
} elseif {
$query .= "quantity > 120 AND id = '$var'";
} elseif {
...
}
...
It all depends on your needs, but neither this or Paper-bat's solutions duplicate query code.