I'm trying to learn a more economical way of parsing out multiple variable values from a single mysql_fetch_array query. I know I could write a whole series of individual queries to resolve this, but that's a lot of extra coding and queries to hit the server with and that just seems grossly inefficient.
The base query I'd like to work with is:
SELECT vehicletype, vehiclelength
FROM my_dbase.my_table
WHERE arriveday = '08/07/2013' AND process_status = 'completed'
vehicletype has one of four fixed values assigned, and vehiclelength has one of five fixed values assigned from option_value fields on a form page.
What I need is to parse the result of the query to count the number of records found for each pair-combination and assign a $variable value to each pair-combination to display in a PHP-generated table. I have four different dates that I need to run this operation for.
I've tried some iterations of creating an array() or using array_count_values() with the output of the mysql_fetch_array result with no success.
Perhaps you can try,
SELECT COUNT(*), vehicletype, vehiclelength
FROM my_dbase.my_table WHERE arriveday = '08/07/2013'
AND process_status = 'completed' and vehicletype
in ('t1','t2','t3','t4') and vehiclelength
IN('1','2','3','3') GROUP BY vehicletype, vehiclelength
ORDER BY vechicletype
I like to let mysql do all the work.
Related
Am using a SQL command in PHP to count the no of values inserted in a column named attack_type. I want to count the occurrence of individual values like website defacement in the whole column of the table. But here the column attack_type contain different values, separated by a comma and the count is treating whole column data as a string. Below is my current SQL statement with its output
I tried explode print_r in PHP
SELECT attack_type,
count(*) as number
FROM data_input_test
GROUP BY attack_type
Here is the output of the above statement
generated:
https://drive.google.com/open?id=1TyRL_Mh0OOJWaCpFczxmBr34No9LUpzH
But what I want is :
https://drive.google.com/open?id=1eeA_1TCER0WMpZwSkBDMzRtRa8xihbZd
and so on. The above desired output is edited to show what I exactly want.
Other answer on stackoverflow and on other forums are either irrelevant or are using regrex or a new table creation in one or the other way. That I don't want as my hosting has some limitations. My hosting doesnt provide creation of triggers, regrex or creation of temp tables
I may have a solution for this but don't know how to apply here. Possible here: https://www.periscopedata.com/blog/splitting-comma-separated-values-in-mysql
Please someone explain me how to apply the same here.
So I finally worked around to get my work done using the select only. This only works if you have a finite set of data or specifically less than 64 values.
Change your column datatype to 'set' type. And enter your set values.
Now use select, count, find_in_set and union functions of sql.
Example:
union select 'Un-patched Vulnerable Software Exploitaion'as type, count(*) as number from data_input_test where find_in_set('Un-patched Vulnerable Software Exploitaion',attack_type)```
and so on for all your values
I know this is not how you should do but as the legends say this works 😎😎
If you just want to count comma-separated values in rows, you can use:
SELECT SUM(LENGTH(attack_type) - LENGTH(replace(attack_type, ',', '')) +1) AS TotalCount
FROM table_name;
There is actually alot of answers for questions like that. But everything I found around here was to Join two tables with "like" values. But that isn't what I need.
I want to query two tables, that is almost exactly the same but with different values inside of it.
tbl_one and tbl_two (exemple names) has "id, title, date, content" its just the same. But inside of tbl_one has differente values of tbl_two.
And then, it's time to query. I could make two queries calling for tbl_one and after tbl_two, but it means that I'll have to print in different "whiles" and I don't want this. I need to print the results in only one "while", so I thought about one query to result from different tables, is that a way to do this?
For make it straight, I need to print the results in a while like this:
while($row = $result->fetch_array()) {
// my results printed
}
Where $result is the result from the query from the two previous tables.
I tried... "select * from tbl_one, tbl_two". Life would be a lot easier if this works.
Use union all to combine your queries i.e.
select * from tbl_one
union all select * from tbl_two
I've spent far too long trying to come up with a good solution to this problem on my own. Haven't found any good answers to help, though I've tried meshing solutions from different answers without luck.
Goal: Present a paginated Projects page containing data from multiple
tables.
I'm using several joins in a single MYSQL query, because I wanted to avoid running queries in a PHP loop. That alone has introduced a fetch_assoc problem, where I had to build my own results array from the while(fetch_assoc) loop because of the repetitive rows resulting from the query. However, the next problem is that the query runs through a pagination class which I use to generate pagination links and get query data like num_rows and such.
So right now, I have a page showing the data I want, but the pagination class is showing me the wrong amount of rows and pagination links. Not sure what the best way is around this problem. Hoping to get some ideas from one of you brilliant experts!
Code is basically:
$sql = "...."
$projects = new pager($sql)
echo $projects->num_rows
while($projects->fetch_assoc){
build new array from data
$project_array[][][]
}
foreach($project_array){
display data from all tables...
}
$projects->showPageLinks
This SQLFiddle provides an example of the data I get:
Notice that there are 7 result rows, but for only 4 projects. So the pagination class shows 7 num_rows (rightfully) but there's only 4 projects.
Any ideas welcome!
I though of maybe concatenating sub query results from other tables into string value in own columns and parsing that with php explode() and such, which would then produce single project rows with all the data, but I haven't been able to accomplish that yet.
Thank you in advance for your help!
The only solution I was able to come up with was to concatenate results from sub queries / joins into single columns in the primary resultset. That allows me to get the results I need without having to modify the pagination class.
See example of concatenated results in this SQLFiddle
Example Query:
SELECT p.id pid, p.name pname, c.name cname,
GROUP_CONCAT(DISTINCT CONCAT_WS('|',w.hours,w.notes,t.name) SEPARATOR ';') as works
FROM projects p
LEFT JOIN (SELECT * FROM clients) AS c ON c.id=p.client_id
LEFT JOIN (SELECT * FROM work) AS w ON w.project_id=p.id
LEFT JOIN (SELECT * FROM tools) AS t ON t.id=w.tool_id
GROUP BY p.id
GROUP_CONCAT(DISTINCT ... is what concatenates the individual rows from the joined results, and the CONCAT_WS('',col,col,..) concatenates the individual result columns. Both allow to you to use separators you define, just like php implode() would. Ultimately, you end up with a formatted string of results in a single column/row on which you can use php to explode() rows and then their columns.
Now I get the right result count, and simply explode the rows and fields by the defined separators.
Example Code:
$wkeys = array('hours','notes','toolname'); // to use as array key (column name)
while($r=$projects->fetch_assoc()){
if(strpos($r['works'],';')!==false){
$wrows = explode(";",$r['works']); // individual rows
foreach($wrows as $k=>$v) {
$wv = explode("|",$v); // individual col=val pairs
$works[] = array_combine($wkeys,$wv);
}
}
}
Hope this helps someone else who may be facing the same situation.
EDIT: While this solution does work quite well for me, I did end up running into a problem with the default length limit for GROUP_CONCAT which is 1024. Any value that was over 1024 was cut down to 1024. See this answer to resolve that. I'd advise you be proactive and change it now, unless you're absolutely sure your values will never be longer than 1024.
$results_ts = mysqli_query($connection, "SELECT id, title, description, content
FROM prose WHERE title LIKE '%$search_title%' LIMIT 10");
if(isset ($_GET['search_title'])){
while($title_arr = mysqli_fetch_array($results_ts)){
echo $title_arr[id]; //and so on...
And that works as I wanted.
but when I try to add , count(*) after where content is, than while() loop echoes only one result, even when $title_arr[4](which stands for count) results in many.
Is it possible to do it this sort of way, or should I be running two separate queries?
You shouldn't do that in one query.
Think about the result you're expecting: when you do a count(*) query, what you get back is a result with only one row and one value. If you select multiple lines, then what should it do? Inject the count into each row of the data?
From a logical perspective, those are two different things you're looking for.
EDIT: counting the rows in your result after the fact is probably the best option, but that won't work if you're only looking for the first 10 entries, and there's no reason to SELECT the whole table if you don't need all the data. That's why count(*) is fulfilling such a different role.
COUNT() is an aggregate function so you can't use it like this. But if all you want is the number of rows this query would have returned you can use SQL_CALC_FOUND_ROWS to get the number of rows that would have been returned if thee was no LIMIT clause. You then can get the results by calling SELECT FOUND_ROWS() after your query is run.
The code:
$review = mysql_query("SELECT conceptID, MIN(nextReview) FROM userconcepts WHERE userID='$userID'");
$nrows = mysql_num_rows($review);
echo "$nrows<br />\n";
The query works when the table has such entries and returns the correct column values. However, when the table is empty, as I can confirm right now in HeidiSQL, mysql_num_rows still returns 1, but the column values are empty. (The problem still remains if the table has other values for different userIDs).
I expect this query to return the empty set sometimes during normal operations, and I want to take action based on the existence of a result, but I also want to use the result if it exists. Any idea why this code is not working as I expect it to work (I expect it to return 0 if the table is empty)?
First of all, the query has a very simple problem: you're showing the conceptID field, but not grouping by it. If you want to show a field on a SELECT that uses aggregate functions, you should show it; not doing so is an error, and will make many engines not execute your query.
That aside, whenever you have an aggregate function, and you don't group by anything (i.e., don't add a GROUP BY clause), the result is one row. Regardless of the amount of rows in the table.
The reason why is because when a SQL engine executes a query with only aggregation functions, then it returns one row. So:
select count(*)
from table
where 1 = 2
is going to return 1 row with the value 0. This is the way that all SQL engines work.
Your query is a little different:
select conceptID, MIN(nextReview)
FROM userconcepts
WHERE userID='$userID'"
In most SQL dialects, you would get an error of the from "conceptID not in group by clause" or something like that. That is, the query would have a syntax error.
MySQL supports this. It will return the minimum value of nextReview (from the rows that meet the where condition) along with an arbitrary value of conceptID (from those same rows). In this case, there are no rows, so the values will be set to NULL.
Perhaps, you want one row per conceptId. That query would be:
select conceptID, MIN(nextReview)
FROM userconcepts
WHERE userID='$userID'
group by conceptId