Desirable result in "UNION" - php

MY sql query is
SELECT id, content FROM table1
UNION ALL
SELECT p_id, p_content FROM table2;
It is giving the desirable result but with column name of first select statement.
e.g
if the query get the data from second select statement it give the result as
array (size=2)
'id' => string '15' (length=2)
'content' => string 'table2 content' (length=22)
i want column name with respective select statement result.
e.g
if select got result from first select then the array of result should be like this
array (size=2)
'id' => string '15' (length=2)
'content' => string 'table1 content' (length=22)
else if select got result from second select statement then the array of result should be like this
array (size=2)
'**p_id**' => string '15' (length=2)
'**p_content**' => string 'table2 content' (length=22)

This is not possible. The column names will be the same throughout the query result. Those column names are actually the column names of the query result and don't need to be the same as column names in the table(s):
SELECT id as Numbers, content as Texts FROM table1
UNION ALL
SELECT p_id, p_content FROM table2;
You can execute two separate queries and process their results separately.
Or otherwise you could return an extra constant value to determine between the results:
SELECT id, content, '1' as TableNr FROM table1
UNION ALL
SELECT p_id, p_content, '2' FROM table2;
Now, for each row you can ask the value of the column 'TableNr' to see which table it came from.

Related

Group SQL query results by year

I'm new in SQL and I need to group the results of a query by year.
In other words, I have this table structure:
id | title | date
My current query SELECT * FROM table
My current result:
array =>
0 =>
array =>
...
'date' => string '2018-03-09'
1 =>
array =>
...
'date' => string '2018-03-15'
2 =>
array =>
...
'date' => string '2017-03-15'
And I need something like that:
array =>
0 =>
array =>
...
'date' => string '2018-03-09'
array =>
...
'date' => string '2018-03-15'
1 =>
array =>
...
'date' => string '2017-03-15'
Thanks in advance for help :)
[EDIT]
I finally found a way to do what I wanted:
$result = $sql->query("SELECT * FROM abstract ORDER BY date DESC");
$array = [];
forEach($result as $res) {
$year = strtok($res['date'], '-');
if (!isset($array[$year]))
$array[$year][0] = $res;
else
array_push($array[$year], $res);
}
return $array;
If you want group data by year.
Select id,title,date,DATE_FORMAT(date, '%Y') YEAR_GRP from table group by YEAR_GRP
This is something you'll want to do in your query, as MySQL can do it much more efficiently, than PHP.
The way to do it is to add a GROUP BY clause to your query, which will batch rows in your resultset into a single row, based on a grouping value, which in your case will be YEAR(date), as you're looking to group items by the year component in each line's date.
Because you're still looking to have all the results returned, merely grouped by each distinct grouping value, you'll need to use an Aggregate Function to combine all the matching lines into an array of values. Luckily MySQL has a function called json_objectagg which does exactly what you need.
So you'll end up with a query that looks something like:
SELECT year(`date`) AS `year`, json_objectagg(id, `date`, title) AS `line`
FROM abstract
GROUP BY `year`
Instead of json_objectagg, alternatives are e.g. json_arrayagg
SELECT year(`date`) AS `year`, json_arrayagg(id, `date`, title) AS `line`
...or group_concat
SELECT year(`date`) AS `year`, group_concat(id, `date`, title) AS `line`
...depending on what kind of output you require.

How to link and display MySQL data from two different tables?

I have two tables named "stats" and "users"
users table has all the typical user data like id,username,password,email(columns)
stats table has id,attack, defense,ostats,gold,food(columns)
I want to display data from these two tables side by side and have the data linked through their IDS
For example,
Rank user_uid ostats attack defense gold
1 Test 10 5 5 100
2 Test2 8 2 6 60
3 Test3 6 5 1 40
Username is from table "users" and the rest of them are from table "stats"
So first I want to know how to link and display the data from the same ID, like Username(user_id=1) and ostats,attack,defense,gold,food(id=1)
Then I want them in order by their "ostats" (I don't have a column named "rank" in any table yet, just don't know how to create the rank using overall stats)
You could do something like (untested)
SELECT u.username, s.overall, s.attack, s.defense, s.gold
FROM stats s JOIN users u on s.user_uid = u.id
ORDER BY s.overall;
Possible solution to ranking:
set #row_number=0;
SELECT (#row_number:=#row_number+1) as rank, u.username, s.overall, s.attack, s.defense, s.gold
FROM stats s JOIN users u on s.user_uid = u.id
ORDER BY s.overall;
Another, horrible looking attempt:
set #row_number = (select count(*) from users) + 1;
select (#row_number:=#row_number-1) as rank, u.username, s.overall from
stats s join users u on s.user_uid = u.id order by s.overall desc;
set #row_number = 0;
Here in PHP code, you have to run it as two queries to set the variable, then run the actual ranking query. This way, the rank variable is always set to 0 when running this. Note that I've used different table and column names, just to simplify things a little. Remember to adjust to your specific needs.
// connect to database
$conn = mysqli_connect("localhost", "user", "password", "database");
// this query will set a variable to 0.
$setSql = "SET #row_number = 0;";
// run the query. This will return a boolean - true or false, depending on whether or not the query ran successfully
$variableSet = mysqli_query($conn, $setSql);
// if the query ran successfully
if($variableSet){
// setup the actual ranking query
$statsSql = "select
(#row_number:=#row_number+1) as rank,
u.id,
u.username,
s.overall
from
mstats s
join
musers u
on
s.muser = u.id
order by
s.overall desc;";
$ranks = mysqli_query($conn, $statsSql);
if(!$ranks){
// dump error from rank query
var_dump($conn->error);
} else {
// dump results as associative array
var_dump($ranks->fetch_all(MYSQLI_ASSOC));
}
} else {
// dump errors from setting variable
var_dump($conn->error);
}
For me, the results dump looks like this:
array (size=3)
0 =>
array (size=4)
'rank' => string '1' (length=1)
'id' => string '2' (length=1)
'username' => string 'Bar' (length=3)
'overall' => string '1000' (length=4)
1 =>
array (size=4)
'rank' => string '2' (length=1)
'id' => string '6' (length=1)
'username' => string 'Tom' (length=3)
'overall' => string '7' (length=1)
2 =>
array (size=4)
'rank' => string '3' (length=1)
'id' => string '1' (length=1)
'username' => string 'Foo' (length=3)
'overall' => string '3' (length=1)

Codeigniter $query->result() returns strange results

This peace of code is driving me crazy for last hour...
I have this model which should return all non active records from DB
$query = $this->db->get($tableName);
echo $this->db->last_query();
var_dump($query->result());
$this->db->last_query() output is
SELECT * FROM `locations` LEFT JOIN `provinces` ON `provinces`.`id_province` = `locations`.`id_province` LEFT JOIN `countries` ON `countries`.`id_country` = `provinces`.`id_country` LEFT JOIN `statuses` ON `statuses`.`id_status` = `locations`.`id_status` WHERE `locations`.`active` = '0' ORDER BY `locations`.`id_location` DESC LIMIT 50
If i run exactsame query in phpmyadmin i get correct results
But when i var_dump data var_dump($query->result()); i get the following results
array (size=50)
0 =>
object(stdClass)[61]
public 'unique_id' => string 'OWYwYjBmNm' (length=10)
public 'active' => string '1' (length=1)
public 'owner_name' => string 'Cleve Greenfelder' (length=17)
1 =>
object(stdClass)[62]
public 'unique_id' => string 'YWY4YmMzMm' (length=10)
public 'active' => string '1' (length=1)
public 'owner_name' => string 'Bradford Hyatt' (length=14)
Why/how this active state get's overwritten from 0 to 1?
IF you need any additional information's, please let me know and i will provide. Thank you!
Once i wrote a question, answer quickly appeared in my head :)
Table Countries has also active field, so this field overwrites active state as enabled. I needed to specified fields and there's name in query in order to get proper results
$fields = 'unique_id, locations.active as active, ....';

How to take Count (*) as variable from SQL to php?

I have made request to SQL:
SELECT meta_value, COUNT(*) from wp_postmeta;
and have in respond an array:
array (size=102)
0 =>
object(stdClass)[24]
public 'meta_value' => string '37' (length=2)
public 'COUNT(*)' => string '147' (length=3)
1 =>
object(stdClass)[23]
public 'meta_value' => string '32' (length=2)
public 'COUNT(*)' => string '143' (length=3)
I take "meta_value" without any troubles with php code:
$result->meta_value;
But how take values of public 'COUNT(*)' => string '143' (length=3)?
I have tried different syntaxis and some errors only.
I need values: 147,143...
Use AS to create an alias
SELECT meta_value, COUNT(*) As count from wp_postmeta;
then use count
Use the alias AS in your SQL to give the MySQL function a desired name.
SELECT meta_value, COUNT(*) as counter from wp_postmeta;
SELECT meta_value, COUNT(*) AS total from wp_postmeta;
This is good solution.
But you can do it alternative way(if you want to keep your query as it is)
$total="count(*)";//keep it inside a variable;
//now you can use it
$result->$total;
$result->count(*) will produce syntax error but $result->$total; will work
You can use a alias name with AS like this:
SELECT meta_value, COUNT(*) as xy from wp_postmeta;
SELECT meta_value,COUNT(*) AS total_count FROM wp_postmeta
echo $result->total_count;

Selecting unique records from mysql with considering only one field

My question may be not reflecting my problem, sorry for that at first. I have a problem , I need to select distinct movie names from a table also selecting its id and other records. But since ids are different for each movies, all the movies are selected(with same name ). Here's the query :
$sql = "
SELECT DISTINCT
movie_id,movie_name
FROM
tbl_current_movies as cm, tbl_movie_hall as mh
WHERE
movie_active = 'active'
AND
cm.hall_id = mh.hall_id
";
$res = $this->db->returnArrayOfObject($sql,$pgin = 'no');
var_dump($res);
And var_dump($res) says :
array
0 =>
object(stdClass)[48]
public 'movie_id' => string '1' (length=1)
public 'movie_name' => string 'MIB' (length=12)
1 =>
object(stdClass)[49]
public 'movie_id' => string '2' (length=1)
public 'movie_name' => string 'Jetuka Pator Dare' (length=17)
2 =>
object(stdClass)[50]
public 'movie_id' => string '3' (length=1)
public 'movie_name' => string 'MIB' (length=12)
So as you can see the movie MIB is showing twice, but I want to get in the results the movies MIB only once !
Change your query to this :
$sql = "SELECT movie_id , movie_name
FROM tbl_current_movies as cm
LEFT JOIN tbl_movie_hall mh ON cm.hall_id = mh.hall_id
WHERE movie_active = 'active'
GROUP BY movie_name
";
You shouldn't join your tables in the WHERE clause, if you're not confortable with the JOINs you can read some of the docs : http://dev.mysql.com/doc/refman/5.0/en/join.html
That should help you understand what they are for.

Categories