PHP trim row results? - php

Hello I'm getting results in format
location1 2 4
location2 3 2
location3 0 0
location1 1 0
How can I trim results so that row returning 0 and 0 is not displayed ? thank you
.................
Here is Mysql query, I don't know how to trim it from MySQL so I thought using PHP ..
SELECT hotelas.name, hotelas.address, hotelas.city, hotelas.country, hotelas.hotel_id
AS hotelid,
COUNT( DISTINCT apart.apartman_id ) AS number_of_free_ap,
COUNT( DISTINCT room.apartman_id ) AS num_of_free_rooms
FROM hotel AS hotelas
LEFT JOIN apartman AS apart ON ( apart.apartman_hotel = hotelas.hotel_id
AND apart.occupied =0
AND apart.what =1 )
LEFT JOIN apartman AS room ON ( room.apartman_hotel = hotelas.hotel_id
AND room.occupied =0
AND room.what =0 )
GROUP BY hotelas.hotel_id
TABLE field what, 0 - for room, 1 - apartment
So I get a few columns among which the most important ones are count columns , free rooms and free apartments. So I have a test hotel which is full 0 rooms and 0 apartments and I want is removed from this list where all other hotels have at least one room or one apartment available.

if you are querying you database to get this information and you can change the query, that would be the best place for it.
SELECT *
FROM myTable
WHERE
firstColumn != 0
OR
secondColumn != 0
If you are getting this in PHP from some other source (CSV or something), or you don't have control over the query, use array_filter():
// i'm assuming each line in your example is an array of values
$myArray = array_filter($myArray, 'noDoubleZeroes');
function noDoubleZeroes($line) {
return $line[1] != 0 || $line[2] != 0;
}

select * from table
where column1 !=0
or column2 !=0
That's how you can trim it in MySQL.
OTOH, if you have an array such as this ( you will usually get this after you query from a db)
array(array('location1', 2, 4), array('location2', 3, 2))
Then you need to loop over the array and do the manual filtering:
$newarrs=array();
foreach($arrs as $values)
{
if($values[1]!=0 || $values[2]!=0)
$newarrs[]=$values;
}
return $newarrs;

If i understood you correctly this should help
$columns = explode($resultLine, " ");
$whatYouWant = $columns[0];

Related

How to count mutiple columns occurrencies in whole table

I have 5 columns that has data which are ids from other table
how do I count how many times each number appears in whole table, in all records.
I want to count paslauga1, paslauga2, paslauga3, paslauga4, paslauga5 data occurrencies.
For example there is 2 records that has 4 times 1 id 2 times 2 id 1 time id 3
So I want it to output
1 has appeared 4 times
2 has appeared 1 times
3 has appeared 2 times
and if more ids would be there 4,5,6 etc it would display them too.
I need to count this so I can use it on php code, maybe theres easier way to do so in php?
Use a simple loop in PHP that counts the numbers in an array.
$counts = array();
$result = $pdo->query("SELECT paslauga1, paslauga2, paslauga3, paslauga4, paslauga5 FROM yourTable");
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
foreach ($row as $col) {
if ($col !=== null) {
if (isset($counts[$col])) {
$counts[$col]++;
} else {
$counts[$col] = 1;
}
}
}
}
ksort($counts);
foreach ($counts as $id => $c) {
echo "$id has appeared $c times<br>";
}
SELECT paslauga, count(paslauga)
FROM (
SELECT paslauga1 as paslauga FROM yourTable
UNION ALL
SELECT paslauga2 as paslauga FROM yourTable
UNION ALL
SELECT paslauga3 as paslauga FROM yourTable
UNION ALL
SELECT paslauga4 as paslauga FROM yourTable
UNION ALL
SELECT paslauga5 as paslauga FROM yourTable
) T
GROUP BY paslauga

Filtering SQL Results with Tags in a Junction Table [duplicate]

Lets consider the following table-
ID Score
1 95
2 100
3 88
4 100
5 73
I am a total SQL noob but how do I return the Scores featuring both IDs 2 and 4?
So it should return 100 since its featured in both ID 2 and 4
This is an example of a "sets-within-sets" query. I recommend aggregation with the having clause, because it is the most flexible approach.
select score
from t
group by score
having sum(id = 2) > 0 and -- has id = 2
sum(id = 4) > 0 -- has id = 4
What this is doing is aggregating by score. Then the first part of the having clause (sum(id = 2)) is counting up how many "2"s there are per score. The second is counting up how many "4"s. Only scores that have at a "2" and "4" are returned.
SELECT score
FROM t
WHERE id in (2, 4)
HAVING COUNT(*) = 2 /* replace this with the number of IDs */
This selects the rows with ID 2 and 4. The HAVING clause then ensures that we found both rows; if either is missing, the count will be less than 2.
This assumes that id is a unique column.
select Score
from tbl a
where a.ID = 2 -- based off Score with ID = 2
--include Score only if it exists with ID 6 also
and exists (
select 1
from tbl b
where b.Score = a.Score and b.ID = 6
)
-- optional? ignore Score that exists with other ids as well
and not exists (
select 1
from tbl c
where c.Score = a.Score and c.ID not in (2, 6)
)

Problems with combining 2 tables with Left Join

I'll try to explain the problem as good as possible.
I have two tables "users1213" which is a table of players and "Loanperiodes". Now I'm trying to get immediately with a sql-query a list of players who is at the moment at the club. If they are on loan to another club they don't have to be on the list. It's also possible that the club is loaning a player so these players have to be on the list as well. So I have this for the moment (the club has an id "1" and the team has also an id "1"):
SELECT users1213.id, surname, name, team, club, loanclub
FROM users1213
LEFT JOIN loanperiode ON users1213.id = loanperiode.player
WHERE users1213.status = 'player'
AND (
(
users1213.club != '1'
AND loanperiode.loanclub = '1'
AND loanperiode.begin <= '2013-02-03'
AND loanperiode.end >= '2013-02-03'
AND (
uitleenperiodes.team_id = '1'
)
)
OR (
users1213.club = '1'
AND users1213.team = '1'
AND (
loanperiode.loanclub IS NULL
OR (
loanperiode.loanclub IS NOT NULL
AND (
loanperiode.begin < '2013-02-03'
AND loanperiode.end < '2013-02-03'
)
OR (
uitleenperiodes.begin > '2013-02-03'
AND uitleenperiodes.end > '2013-02-03'
)
)
)
)
)
GROUP BY users1213.id
ORDER BY name
LIMIT 0 , 30
With this query I get a good result but there is 1 problem, when someone had got 2 loanperiodes. For example PLAYER1 is loaned now to CLUB A so he may not be listed. But when PLAYER1 has also got a loanperiode which has already expired, to CLUB B, PLAYER1 will be listed because of the LEFT JOIN. Is there a solution to solve this with a query or must I check afterwards when I'm running the array?
Many thanks!
SELECT users1213.id, surname, name, team, club, loanclub
FROM users1213
LEFT JOIN loanperiode ON users1213.id = loanperiode.player
AND '2013-02-03' BETWEEN loanperiode.begin AND loanperiode.end
WHERE
loanperiode.loanclub = '1'
OR (loanperiode.loanclub IS NULL -- I suppose this happens only when there is no loan between those dates so nothing LEFT JOINed
AND users1213.club = '1')
ORDER BY name
This example supposes that user can have only one loan at once (yes, he can have more loans ended in history, but only one begins before today and ends in the future).

Retriving an array of grouped elements in mysql (+php)

I need i bit of help with this query, so far i have this:
SELECT * FROM coupons WHERE discount_id = '1' AND client_username = 'Zara' GROUP BY winner_id
The table is like this
id client_username winner_id bdate discount_id destroyed
72 zara 1125405534 2012-11-11 03:34:49 4 0
71 zara 1125405534 2012-11-11 03:34:43 1 0
70 zara 1125405534 2012-11-11 03:34:27 1 0
I want to group the result by winner_id (its a unique user id) where discount_id is equal to some value and order by bdate, the think is I need the id bdate and destroyed value of each ocurrence of the user and also count the number of times winner_id appear, so the result needs to be a value (count of how many times winner_id appears), and 3 arrays (discount_id,destroyed,id).. But I have no idea how to retrive this in the way I need. Thanks for any help!
Two basic methods:
aggregate in mysql and "explode" in php
aggregate in PHP
number 1 involves using some aggregate functions in your query, like COUNT() and GROUP_CONCAT():
SELECT count(*) as num_wins, GROUP_CONCAT(discount_id, ',') as discount_ids ...
then in PHP, these GROUP_CONCAT columns can be "exploded" into arrays while looping over the results:
foreach($rows as $row) {
$discount_ids = explode(',', $row['discount_ids']);
// ...
}
number 2 is easier SQL, but uglier PHP. Basically just select all your rows, and then pre-process the results yourself. (I recommend the previous solution)
foreach($rows as $row) {
$results_tree[$row['winner_id']]['num_wins']++;
$results_tree[$row['winner_id']]['discount_ids'][] = $row['discount_id'];
// ...
}

MySQL greatest value in row?

I'm using MySQL with PHP. This is like my table: (I'm using 3 values, but there are more)
id | 1 | 2 | 3
---+---+---+----
1 | 3 |12 |-29
2 | 5 |8 |8
3 | 99|7 |NULL
I need to get the greatest value's column name in a certain row. It should get:
id | maxcol
---+-------
1 | 2
2 | 2
3 | 1
Are there any queries that will do this? I've been trying, but I can't get it to work right.
Are you looking for something like the GREATEST function? For example:
SELECT id, GREATEST(col1, col2, col3)
FROM tbl
WHERE ...
Combine it with a CASE statement to get column names:
SELECT id, CASE GREATEST(COALESCE(`1`, -2147483646), COALESCE(`2`, -2147483646), COALESCE(`3`, -2147483646))
WHEN `1` THEN 1
WHEN `2` THEN 2
WHEN `3` THEN 3
ELSE 0
END AS maxcol
FROM tbl
WHERE ...
It's not pretty. You'd do better to follow Bill Karwin's suggestion and normalize, or simply take care of this in PHP.
function findcol($cmp, $arr, $cols=Null) {
if (is_null($cols)) {
$cols = array_keys($arr);
}
$name = array_shift($cols);
foreach ($cols as $col) {
if (call_user_func($cmp, $arr[$name], $arr[$col])) {
$name = $col;
}
}
return $name;
}
function maxcol($arr, $cols=Null) {
return findcol(create_function('$a, $b', 'return $a < $b;'), $arr, $cols);
}
This is a great example of the way normalization helps make query design easier. In First Normal Form, you would create another table so all the values would be in one column, on separate rows.
Since you have used repeating groups to store your values across three columns, you can find the column with the greatest value this way:
SELECT id, IF(col1>col2 AND col1>col3, 'col1', IF(col2>col3, 'col2', 'col3'))
AS column_with_greatest_value
FROM mytable;
The short answer is that there is no simple means to do this via a query. You would need to transpose your data and then determine the largest value that way. So something like:
Select Id, ColumnName, Value
From (
Select '1' As ColumnName, Id, [1] As Value
From Table
Union All
Select '2', Id, [2]
From Table
Union All
Select '3', Id, [3]
From Table
) As Z
Where Exists(
Select 1
From (
Select '1' As ColumnName, Id, [1] As Value
From Table
Union All
Select '2', Id, [2]
From Table
Union All
Select '3', Id, [3]
From Table
) As Z2
Where Z2.Id = Z.Id
Group By Z2.Id
Having Max(Z2.Value) = Z.Value
)
Order By Id
This solution depends on a fixed set of columns where you basically name the columns in the UNION ALL queries. In addition, if you have two columns with identical values for the same Id, you will get duplicate rows.
This query will return the max value regardless of NULLs
SELECT MAX(value)
FROM
(SELECT 1 column_no, col1 value
FROM anotherunamedtable
UNION ALL
SELECT 2, col2
FROM anotherunamedtable
UNION ALL
SELECT 3, col3
FROM anotherunamedtable) t
If you really need the column number then
SELECT id,
(SELECT column_no
FROM
(SELECT 1 column_no, col1 value
FROM anotherunamedtable
WHERE id = t.id
UNION ALL
SELECT 2, col2
FROM anotherunamedtable
WHERE id = t.id
UNION ALL
SELECT 3, col3
FROM anotherunamedtable
WHERE id = t.id) s
ORDER BY max_value DESC
LIMIT 1)) as column_no
FROM anotherunamedtable t
But I think that the last query might perform exceptionally horrible.
(Queries are untested)
In the php side, you could do something like this:
foreach ($rows as $key => $row) {
$bestCol = $best = -99999;
foreach ($row as $col => $value) {
if ($col == 'id') continue; // skip ID column
if ($value > $best) {
$bestcol = $col;
$best = $value;
}
}
$rows[$key]['best'] = $bestCol;
}
Or something similar...
Forests and trees, here's a trivial and fastest solution (providing I didn't fumble); the expression simply looks for the largest column in the row
SELECT id,
CASE COALESCE(col1, -2147483648) >= COALESCE(col2, -2147483648)
WHEN
CASE COALESCE(col2, -2147483648) >= COALESCE(col3, -2147483648)
WHEN true THEN 1
ELSE
CASE COALESCE(col1, -2147483648) >= COALESCE(col3, -2147483648)
WHEN true THEN 1
ELSE 3
END
END
ELSE
CASE COALESCE(col2, -2147483648) >= COALESCE(col3, -2147483648)
WHEN true 2
ELSE 3
END
END
FROM table t
a version with IF() would maybe be more readable, but the above should perform a bit better
To deal with NULLS an INT value with minimum of -2147483648 was assumed, the expression could be rewritten to deal explicitly with nulls but would have to branch into 8 different cases and is left as an exercise for the OP.

Categories