Is it possible to write a function within mySQL that checks the value of a SELECT query, and if it != 0, continue running the function and add to the result array?
I have a few entries marked as related_id = 0 The rest have actual positive numbers attached.
I am trying to create a single query that will continually loop through a sql function, check and see if the retrieved related_id result is 0. If not, then it will run again, add the newly checked row to the result array and continue until it finds a 0.
The way the DB is set up, a 0 will always occur, and it will be searching via id,so there should only be one result.
I am using a slightly modified tagging system.
keywords_id | keyword | related_id
------------------------------------
1 | sports | 0
2 | baseball | 1
3 | football | 1
4 | pitchers | 2
If I pass in related_id = 2 I'm looking to return an array that yields:
array
[0]
keyword => 'sports'
keywords_id => '1'
related_id => '0'
[1]
keyword => 'baseball'
keywords_id => '2'
related_id => '1'
[2]
keyword => 'pitcher'
keywords_id => '4'
related_id => '2'
I tried my luck with using IF and THEN but i just haven't seen enough examples and its tough to find solid tutorials online. Thanks!
SELECT k.*
FROM keywords k
WHERE keywords_id = 2
The above query would essentially start it off. The keywords_id is the related_id that is passed. Therefore the above would return keywords_id: 2 |keyword: baseball |related_id: 1
Because related_id 1 is NOT 0, i would need to run it again.
I realize this can be done in PHP through a few extra queries...is that the way I should do this? I assume it could be done in mySQL after reading about functions. I just couldn't figure it out.
MySQL doesn't support returning an array from a function. Would suggest creating a table (or possibly a temporary table) to hold the results and then writing a stored procedure to populate it instead.
Not sure exactly what you are trying to achieve but maybe something along the lines of this?
CREATE TABLE results (keywords_id INT, keyword VARCHAR(2000), related_id INT);
CREATE PROCEDURE populateResults(IN keyword_id_in INT)
BEGIN
DECLARE num_results INT;
DECLARE max_results INT;
DECLARE next_keyword_id INT;
SET next_keyword_id = keyword_id_in;
SET max_results = 5;
SET num_results = 0;
DELETE FROM results;
the_loop: LOOP
INSERT INTO results
SELECT keywords_id, keyword, related_id
FROM keywords
WHERE keywords_id = next_keyword_id;
SELECT related_id
FROM keywords
WHERE keywords_id = next_keyword_id
INTO next_keyword_id;
IF (next_keyword_id = 0) || (num_results >= max_results) THEN
LEAVE the_loop;
END IF;
SET num_results = num_results + 1;
END LOOP the_loop;
END
See SQL Fiddle Demo
My understanding from above sample - need to get all records checked until a match is found ( the above sample for related_id = 2 ).
If so you can try using mysql cursors http://dev.mysql.com/doc/refman/5.0/en/cursors.html
in order to loop the result set.
Related
table
-----
id column1
1 some random text
2 more random text
3
4 blah blah
5
6
7
8
9
$sqlData7 = $this->con->prepare("SELECT id, column1 FROM table WHERE column1 IS NOT NULL");
$rowTotal7 = $sqlData7->rowCount();
$attIdArr7 = $sqlData7->fetchAll(PDO::FETCH_COLUMN, 0);
print_r($attIdArr7);
This should return:
Array ( [0] => 1 [1] => 2 [2] => 4 )
but is returning
Array ( )
What am I doing wrong that it is not picking up the not null columns?
I don't think I need an additional boolian column "is_column1_Null" that I can query but after half a day trying to get this to work I am about to add it.
many thanks
You need to call $sqlData7->execute()
<?php
$sqlData7 = $pdo->prepare("SELECT id, column1 FROM `table` WHERE column1 IS NOT NULL");
$sqlData7->execute();
$rowTotal7 = $sqlData7->rowCount();
$attIdArr7 = $sqlData7->fetchAll(PDO::FETCH_COLUMN, 1);
var_dump($attIdArr7);
PHP PDO Online test
You can do write the following query to get the expected result
SELECT id, column1 FROM table column1 IS NOT NULL AND TRIM(column1) <> '';
The above database design suggest that the column is empty and not set to null but can be null also. So I check for two conditions, check if the column is not null and also to check whether it's not empty. I think it's inserting data without any validation, so it's insert empty values too.
I need an SQL query to do the following task:
I have two columns. Column 'foo' and column 'bar'.
The query needs to return results if and only if column 'foo' has different values but 'bar' has the same values.
For example:
Foo Bar
---------------------
1 John
1 Lee
2 James
3 Robin <- the value '3' needs to be returned
3 Sally
1 Peter
1 John
4 Brian
2 Robin <- the value '2' needs to be returned
If I was to run the query on the above dataset, then both rows indicated withe arrows above would be returned, because 'bar' is the same on both rows, but 'foo' is different.
Any help would be appreciated.
Thank you.
You can do what you want using exists:
select t.*
from t
where exists (select 1
from t t2
where t2.bar = t.bar and t2.foo <> t.foo
);
QUERY:
SELECT month(date_created), count(a.ticket_num)
FROM ticket as a
LEFT JOIN user_management as b on b.engineer_id = a.ticket_engineer
WHERE b.tl_id = 'sample_id'
AND year(date_created) = '2019'
GROUP BY extract(year from date_created), extract(month from date_created)
SAMPLE OUTPUT:
month | ticket_num
----------------------
2 | 12
4 | 24
6 | 78
EXPECTED SAMPLE OUTPUT:
month | ticket_num
----------------------
1 | 0
2 | 12
3 | 0
4 | 24
5 | 0
6 | 78
As you can see the above expected output, i'm trying to place all existing month in the first column and set all the count to zero if not existed in the second column. As of now, i only have the query for sorting the ticket count by month that is existed when the ticket is created.
There are different approaches to this problem. One is pure SQL for example.
But I would say a PHP based solution is simpler. Basically you need to get your data into array, then create a loop that outputs the desired months order, and have a condition that sees whether we have a corresponding row in our array and outputs ether the actual data or a zero accordingly.
The only tricky part is to have such an array that would let us check the data availability. For this we have to index it with month numbers. Not a big deal actually
$sql = "SELECT month(date_created), count(a.ticket_num) ...";
$res = $mysqli($sql);
$data = [];
while($row = mysqli_fetch_row($res)) {
$data[$row[0]] = $row[1];
}
Now $data is an array indexed by the month number. The rest is a primitive loop
foreach (range(1,12) as $month) {
echo $data[$month] ?: 0;
}
On a side note I would like to advertise using PDO as opposed to mysqli for your database interactions as this case clearly displays the superiority of the former. Using PDO we can get the indexed array right away, without an explicit loop, thanks to a special fetch mode:
$sql = "SELECT month(date_created), count(a.ticket_num) ...";
$data = $data = $pdo->query($sql)->fetchAll(PDO::FETCH_KEY_PAIR);
That's all!
I am attempting to create an end-user page where I present different servers that are available to check-out. A server at any given time can have either an "Available" status or a "Reserved" status. I'm using a MySQL backend. This is how I am doing my query:
SELECT *, COUNT(CASE WHEN Status = 'Available' THEN 1 ELSE NULL END) AS Amount
FROM products GROUP BY id
This is the result I get:
id,Server_Type,Status,Amount
1,BL460,Available,1
2,BL460,Available,1
3,BL460,Reserved,0
4,BL460,Reserved,0
5,BL460,Reserved,0
6,DL360,Available,1
7,DL360,Reserved,0
8,DL360,Reserved,0
Where Reserved is equal to 0, and Available is equal to 1. I only want the end-user to be able to checkout a server in Available status.
To the question: What I want to do in the page is present the list of servers on the page in this way, where Available is equal to the amount:
BL460 - Amount: 2
DL360 - Amount: 1
How can I achieve this format in PHP?
Another option is a crosstab query -
SELECT `Status`,
SUM(IF(`Server_Type` = 'BL460' AND `Status` = 'Available', `Amount`, 0)) AS `BL460`,
SUM(IF(`Server_Type` = 'DL360' AND `Status` = 'Available', `Amount`, 0)) AS `DL360`
FROM `products`
GROUP BY `Status`
Your table would look like this -
Status | BL460 | DL360 |
Available | 2 | 1 |
Reserved | 0 | 0 |
Here is an EXAMPLE
Even better would be to flip things around -
SELECT `server_type`,
SUM(IF(`status` = 'Available', 1, 0)) AS `Available`,
SUM(IF(`status` = 'Reserved', 1, 0)) AS `Reserved`
FROM `servers`
GROUP BY `server_type`;
Which would result in a table that looks like this (based on data in the fiddle) -
server_type | Available | Reserved
BL460 | 3 | 1
DL360 | 1 | 2
Here is that EXAMPLE
Here I could continue to add servers to the table without having to worry about adding them to the query as you would have to do in the first query. If you add an additional status you would have to change the query.
Note in both cases there is no need for an Amount column as the status is the item counted. By placing the load on the database server it makes it much easier to output the HTML as you are just going row bu row as you normally would.
Well, that would probably be easier if you do it directly in your SQL query:
SELECT Server_Type, COUNT(*) AS Count FROM products WHERE Status = 'Available' GROUP BY Server_Type
This should give you exactly the table you want.
If you want to do it in PHP, the easiest solution would probably be to loop through your SQL result and count the number of available servers per Server_Type in an associative array where the Server_Type is your array key:
$amounts = array();
foreach($sql_result as $entry) {
if($entry['Amount'] == 1) {
if(isset($amounts[$entry['Server_Type']])) {
$amounts[$entry['Server_Type']]++;
} else {
$amounts[$entry['Server_Type']] = 1;
}
}
}
echo $amounts;
Edit: in order to print the values as described in the question, you could use the following code snippet:
foreach($amounts as $name=>$amount) {
echo $name + " - Amount: " + $amount + "<br>";
}
am new here, but have enjoyed reading others' questions and answers. I'm fairly new to PHP and am working on a project - basic table look-ups in MySQL, etc.
What I want to end up with is an array of arrays, the form of which is shown below with condiments (not my actual project). The content is coming from two different tables. For each of the condiment names (from table 1) I look up in table 2 the types of condiments, linked by ID. The searching and grabbing stuff is fine, but I'm having trouble looping and building my final $Condiments array.
The first part of the loop, I grab the condiment name from the $row and append it to the array. But I need each of these condiment names to be an empty array to put something in, in the next step. I've looked around but couldn't find a good way to iteratively append new placeholder arrays into an array. Is there an elegant solution? Some cool function I'm not taking advantage of? Thanks!
// SQL search for condiment words, blah blah, leading to...
$rowsnumber = mysql_num_rows($result);
for ($j = 0 ; $j < $rowsnumber ; ++$j)
{
$row = mysql_fetch_row($result); // $row is an array featuring a condiment name and other stuff.
$Condiments[] = $row[1]; // condiment name goes in array.
$CondimentType = searchTable2($row[0]);
// using the condiment name's ID, I look up its matching types via a function.
// $CondimentType is now an array of IDs and types from Table2 that I want to append to the condiment name I just added above.
$Condiments[$row[1]] = $CondimentType;
// I repeat the process for the next name
}
// Final desired result...
$Condiments=
Array
(
[Pickles] => Array
(
[34] => Dill
[23] => Butter
)
[Mustard] => Array
(
[22] => Hot
)
[Relish] => Array
(
[3] => Pickle
)
)
so like i said , you need to use join to perform the needed task.
you can find more explanation here about joins
http://dev.mysql.com/doc/refman/5.0/en/join.html
in your case , this query should do the job
select t1.word,t3.word
from table1 as t1 join table2 as t2 on t1.id =t2.id
left join table1 as t3 on t3.id = t2.linkid
i ran the query in my machine and these are the results
+---------+--------+
| word | word |
+---------+--------+
| Pickles | Dill |
| Pickles | Butter |
| Mustard | Hot |
| Relish | Pickle |
+---------+--------+
so instead of looping through each row, just perform a join and get the results. in php then you can do the needed format of the array.
hopefully this will help you