I'm trying to get multiple sums of rows, each sum has a matching column string value, and all the values have a matching 4 character prefix, but it's not working and I could use some help. Also, would CASE be a more or less costly query on the db?
Started with this:
$sql =
"SELECT col1
FROM table
WHERE substr(col1,1,5)='$string'";
$query = mysqli_query($con, $sql);
$row = mysqli_fetch_array($query,MYSQLI_ASSOC);
$results = $row['col1'];
$sum1 = count(array_keys($results,'string1'));
$sum2 = count(array_keys($results,'string2'));
Does it work to get the results from the same column that's in the WHERE clause?
In practice, col1 has row values like aaaa_string1, aaaa_string1, aaaa_string2, aaaa_string2, bbbb_string8... so I'm looking to get all col1 results that have the aaaa in an array, then subsequently filter how many exist of each string1 and string2.
Use SUBSTR(col1, LENGTH('$string')+1) to get the part of the column after the prefix, and group by this.
Use LIKE 'prefix%' to match a column beginning with a prefix.
SELECT SUBSTR(col1, LENGTH('$string')+1) AS suffix, COUNT(*) as count
FROM table
WHERE col1 LIKE '$string%'
GROUP BY suffix
Then you can use a loop to create an associative array with all the counts:
$counts = array();
while ($row = mysqli_fetch_assoc($query) {
$counts[$row['suffix']] = $row['count'];
}
var_dump($counts);
Looking at you code seems that you are trying to get the cout for substring 'string1' or 'string2' in col1
"select col1, count(*) as col_count
from table
WHERE substr(col1,1,5)= '$string'
and col1 in ('string1','string2')
group by col1"
You should retrive the result in col_string and col_count
for suffix (assuming char 6 to end)
"select bstr(col1, 6, 100), count(*) as col_count
from table
WHERE substr(col1,1,5)= '$string'
and substr(col1, 6, 100) in ('string1','string2')
group by bstr(col1, 6, 100)"
Related
Suppose I have a table TABLE:
NAME ID ...
m -1 ...
f -1 ...
g -1 ...
b -1 ...
z -1 ...
And I want to turn it into:
NAME ID ...
f 1 ...
g 2 ...
m 3 ...
b -1 ...
z -1 ...
You probably get the idea:
select the first 3 rows from the original table (preserving order)
order selected rows by the NAME column.
update selected rows' IDs with their position in the new table (keeping the remaining unselected rows in their original positions).
So (m, f, g) got sorted to (f, g, m) and (b, z) remained (b, z).
Here's how I am trying to do it in PHP:
$count = 0;
$query = "UPDATE TABLE SET ID = $count:= $count + 1 ORDER by NAME DESC LIMIT 3";
mysqli_query($con, $query);
But I don't think I can just go ahead and increment a counter and store its value like that. Any advice?
You can try this :
$limit = 3;
for($count = 0 ; $count < $limit;$count++ ){
$query = "UPDATE TABLE SET ID = $count + 1 WHERE ID = '-1' ORDER by NAME DESC";
mysqli_query($con, $query);
}
$query = "UPDATE TABLE SET ID = '-1' WHERE ID > $limit ORDER by NAME DESC";
mysqli_query($con, $query);
In the above logic :
In the final loop, all the IDs are set to $limit
However the update command outisde the loop will set back IDs to -1 again
First, you can quickly query for the first 3 rows in the table and get the name property only and assign the value in an array.
$sql = "select name from table order by name limit 3"
$query = $mysqli->query($sql);
Now let's construct a helper array:
while ($row = $mysqli->fetch_assoc()) {
$a[] = $row['name'];
}
Now just structure the queries:
foreach($a as $id => $name) {
$query = "update table set id={$id+1} where name='$name' limit 1";
// execute the query
}
Note that I assume that the name is unique so I added the limit 1 directive to tell it stop looking for rows to update once it has found a row.
Also, don't forget that array keys are counting starting from 0, hence we are adding 1 to the $id in the loop.
There may be more elegant solutions but this one is rather easy to understand and use.
In MySQL:
SET #row_number = 0;
update TABLE d
join
(
select
NAME,
#row_number:=#row_number+1 as ID,
from
(select NAME from TABLE limit 3) t
order by
NAME asc
) s on s.NAME = d.NAME
set d.ID = s.ID;
SQLFiddle: http://sqlfiddle.com/#!9/dffecf/1
This assumes NAME is your unique key, otherwise likely best to replace with an Identity column in your table and use that for the update.
This approach may require some syntax changes depending on your DB engine. By doing this in SQL, we only make one pass at the DB. Not a huge deal to iterate in multiple passes with PHP if you're only updating three records, but if it was a 1000, etc.
I have a a table in my DB that has multiple columns with numbers I would like to query all the rows in 1 query with separate totals for all rows in each column in my db.
like so
$sql = '
SELECT sum(TOTAL1)
, sum(TOTAL2)
, sum(TOTAL3)
, sum(TOTAL4)
FROM TABLE WHERE ID = '.$ID.'';
it works when I do it with a single column query like this.
$sql = 'SELECT sum(TOTAL1) FROM TABLE WHERE ID = '.$ID.'';
but I can't seem to get it to work for multiples in 1 query does anyone know of a more proper way of doing this instead of in separate queries?
$sql = 'SELECT (sum(TOTAL1)+sum(TOTAL2)+sum(TOTAL3)+sum(TOTAL4)) AS FINALTOTAL FROM TABLE WHERE ID = '.$ID.'';
Use aliases.
Sidenote: Add your WHERE clause to the tested examples I've given below.
SELECT sum(TOTAL1) as total1, sum(TOTAL2) as total2
which if you want to use seperate aliases, is handy if you wish to echo them as different entities.
For example:
$query = mysqli_query($con, "SELECT SUM(col1) as total1,
SUM(col2) as total2,
SUM(col3) as total3 FROM table ");
while($row = mysqli_fetch_array($query)){
echo $row['total1']; // echo'd 125
echo "<br>";
echo $row['total2']; // echo'd 225
echo "<br>";
echo $row['total3']; // echo'd 2000
}
Sidenote: My three columns contained the following:
col1 in 2 rows 25, 100
col2 in 2 rows 25, 200
col3 in 2 rows 1000, 1000
To echo the total of all rows and for example: (and inside the while loop)
$total = $row['total1'] + $row['total2'] + $row['total3'];
echo $total;
Or in one go and as one alias and one row echo'd:
SELECT sum(TOTAL1 + TOTAL2 + TOTAL3) as total FROM table
I.e.:
$query = mysqli_query($con, "SELECT SUM(col1 + col2 + col3) as total FROM table ");
while($row = mysqli_fetch_array($query)){
echo $row['total'];
}
NOTE: DATA TYPE must be same for all fields which you want to SUM
By following query you can have SUM(field1)+SUM(field2)+ SUM(field3) .....n in 1 single field
I used this query for just 2 fields and both are integers
See this is my table definition
create table `siso_area_operativa` (
`id_area_operativa` int ,
`area_operativa` varchar (8),
`responsable` int
);
and this is query which you want
SELECT SUM(a.field1) FROM
(
SELECT
SUM(id_area_operativa) field1
FROM
siso_area_operativa
UNION ALL
SELECT SUM(responsable) field1
FROM
siso_area_operativa ) AS a
Result of this is
SUM(id_area_operativa) + SUM(responsable) in single field
ENJOY !!!!!!!!!!!!
I'm trying to create a insert query which contains a select query. The problem is that it does not seem to work, but they work separately.
The select query select the highest number from the numbers table and then it need to add 1 to it. the $variables is from php.
What am i doing wrong?
INSERT INTO numbers (number, storeID, udid)
VALUES (
(SELECT number
FROM numbers
WHERE storeid = '$var' AND DATE(timestamp) = CURDATE()
ORDER BY number DESC LIMIT 1
) + 1, $var, $udid)
You may create a variable storing the incremented value first
$results = mysqli_query($con, "Select number FROM numbers where storeid= '$var' AND DATE(timestamp) = CURDATE() Order by number DESC LIMIT 1");
if ($row = mysqli_fetch_array($results))
{
extract($row);
$incremented_value = $row['number'] + 1;
}
Then, the number of columns must be identical
INSERT INTO numbers (number, storeID, udid)
VALUES
($incremented_value, $var, $udid)
Ok, so I have some MySQL tables as follows:
Buildings
Building-ID Building-Name
===========----=============
1 Building-1
2 Building-2
3 Building-3
4 Building-4
Building-1
Mroom State
=====----======
1 Booked
2 Empty
3 Empty
4 Empty
Building-2
Mroom State
=====----======
1 Booked
2 Empty
3 Empty
4 Empty
And a query in PHP as follows (Ignore the hard coded while, I've simplified the code a bit):
$sql = "select * from Buildings";
$result = mysql_query ($sql) or die(mysql_error());
while ($row = mysql_fetch_array($result))
{
$building[] = $row['ward_name'];
}
$v1 = 0;
while ($v1 < 4)
{
$sql = "SELECT COUNT(*) FROM `$building[$v1]` WHERE state = 'Empty'";
$result = mysql_query($sql) or die(mysql_error());
$count = mysql_result($result, 00);
var_dump($count[$v1]);
$v1 = $v1 + 1;
}
To my way of thinking this should create an array of the buildings contained in the "Buildings" table, start a loop, load the building name from the array and provide a row count for the table of how many rows contain "Empty" in the state column. What it actually does is provide a count for the first table and then provides "NULL" for the rest.
I'd appreciate any help you can give me.
Cheers!
What about changing your data model?
Table buldings can be kept as is:
Buildings
Building-ID Building-Name
===========----=============
1 Building-1
2 Building-2
3 Building-3
4 Building-4
New table:
Rooms
Building-ID Mroom State
===========-=====-=====
1 1 1
1 2 0
2 1 0
State 0 = Empty, State 1 = Booked
Then use a join with group by:
select count(*) from buildings b inner join rooms r on r.bid = b.id where r.state = 0 group by b.id;
Then you will get a row for each building with the count of empty rooms. You won't need a table for each building.
This does noit make sense:
$count = mysql_result($result, 00);
var_dump($count[$v1]);
you mean to write:
$count[$v1] = mysql_result($result, 00);
var_dump($count[$v1]);
Also do not use several tables with names matching columns of other tables.
You can use one table with a primary key that spans two columns instead, for example create primary key on($buildingid,$roomid)
so that the table has columns $buildingid,$roomid, and $state.
mysql_result() returns a string, not an array.
Modify the code and check that now it works as expected.
var_dump($count);
I am creating a simple SQL query in PHP - and for some reason, even when DISTINCT is used, it shows twice like this:
BC
BC
OH
OH
TX
TX
Here is my code:
<?php
$sql = "SELECT DISTINCT `title`,`extra_fields_search` FROM `blahblah_items` WHERE catid=336 ORDER BY `blahblah_items`.`extra_fields_search` ASC ";
$partnerlisting= mysql_query($sql) or die(mysql_error());
while($row = mysql_fetch_assoc($partnerlisting))
foreach($row as $cname => $cvalue){
echo '<li>'.substr($row[extra_fields_search], 0, 2).'</li><br>';
}
;
?>
How can I make it so it prints out only one of each?
SELECT
`title`,
`extra_fields_search`
FROM
`blahblah_items`
WHERE
catid=336
GROUP BY
SUBSTRING(extra_fields_search,1,2) # here. group by first two characters of extra_fields_search
# or just "GROUP BY extra_fields_search", depends what you need
ORDER BY
`blahblah_items`.`extra_fields_search` ASC
SELECT DISTINCT a,b FROM table works in same way as SELECT a,b FROM table GROUP BY a,b
Please follow documentation:
http://dev.mysql.com/doc/refman/5.0/en/distinct-optimization.html
http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html
Distinct make sure that you get unique rows. It does not make sure you will get unique column values. In your case if you consider all the fields in the result, you will notice that each row is different from the other by at least one field.
SO you will never get
Col1 Col2
A B
A B
But you can get
Col1 Col2
A B
A C
Try:
SELECT `title`, group_concat(distinct `extra_fields_search`)
FROM `blahblah_items`
WHERE catid=336
Group BY `title`
ORDER BY 2
try this
SELECT `title`,`extra_fields_search`
FROM `blahblah_items` WHERE catid=336
Group BY extra_fields_search
ORDER BY `blahblah_items`.`extra_fields_search` ASC
edit :
try this in your code
while($row = mysql_fetch_assoc($partnerlisting))
$rows[] = $row;
foreach($rows as $row){
echo '<li>'.substr($row[extra_fields_search], 0, 2).'</li><br>';
}
;