How to query rows from 2 tables in a single query? - mysql

TABLE 1
student_id | name
-----------------
1 | A
2 | B
3 | C
4 | D
TABLE 2
vote_id | student_id | vote_for
------------------------------
1 | 1 | 2
2 | 1 | 3
3 | 2 | 1
4 | 1 | 4
How can I get records from TABLE 1 (student names B C D) based on student_id in TABLE 2 (student_id 1) in a single query? I managed to do it but in multiple queries like below:
$students = array();
$query = "SELECT vote_for FROM table2 WHERE student_id=?";
$stmt = $this->con->prepare($query);
$stmt->bind_param("i",$student_id);
$stmt->execute();
$stmt->bind_result($vote_for);
$votes = array();
while($stmt->fetch()){
$votes[] = $vote_for;
}
$stmt->close();
if (!empty($votes)) {
$query = "SELECT name FROM table1 WHERE student_id=?";
foreach ($votes as $vote) {
$stmt = $this->con->prepare($query);
$stmt->bind_param("i",$vote);
$stmt->execute();
$stmt->bind_result($name);
while($stmt->fetch()){
$temp = array();
$temp['name'] = $name;
$students[] = $temp;
}
$stmt->close();
}
}

You can use a JOIN query to get the names of the students that were voted for by a given student_id. For example:
SELECT s.name AS voted_for
FROM table2 v
JOIN table1 s ON s.student_id = v.vote_for
WHERE v.student_id = 1
Demo on dbfiddle
In PHP:
$students = array();
$query = "SELECT s.name AS voted_for
FROM table2 v
JOIN table1 s ON s.student_id = v.vote_for
WHERE v.student_id = ?";
$stmt = $this->con->prepare($query);
$stmt->bind_param("i",$student_id);
$stmt->execute();
$stmt->bind_result($name);
while($stmt->fetch()) {
$students[] = array('name' => $name);
}
$stmt->close();

I believe you can achieve it with the following query:
SELECT T1.STUDENT_ID, T1.NAME
FROM TABLE_1 T1, TABLE_2 T2
WHERE T1.STUDENT_ID = T2.VOTE_FOR
AND T2.STUDENT_ID = ?
And you would just inject the STUDENT_ID for the Table 2. You can remove the T1.STUDENT_ID if necessary.

Related

How to query CodeIgniter in two table with condition?

I got headache of this query issue in CodeIgniter
I'm a beginner of this framework
How to query in CodeIgniter of Query result in Table 1 and Table 2.
If you are using the Query Builder in Codeigniter version 3 (I assume since your using the tag codeigniter-3), then you could specify the columns in your select statement and use join to achieve what you want:
$this->db->select('t1.Account, t1.Client, t1.Wala, t2.Meron');
$this->db->from('Table1 t1');
$this->db->join('Table2 t2', 't1.Account = t2.Account AND t1.Client = t2.Client');
$this->db->where('t1.Account', 111); // IF YOU ONLY WANT A SPECIFIC ACCOUNT
$this->db->group_by('t1.Account, t1.Client');
$query = $this->db->get();
if ($query->num_rows() > 0){
$result = $query->result(); // ARRAY OF OBJECTS
foreach ($result as $r){
echo $r->Account."\t";
echo $r->Client."\t";
echo $r->Wala."\t";
echo $r->Meron."\n";
}
}
The result:
| Account | Client | Wala | Meron |
|---------|--------|------|-------|
| 111 | Doe | | 50 |
| 111 | Jhon | 200 | 50 |
Documentation: https://www.codeigniter.com/userguide3/database/query_builder.html
Alternatively, you can use a pure SQL query to get the same result:
$sql = 'SELECT t1.Account, t1.Client, t1.Wala, t2.Meron
FROM Table1 t1
JOIN Table2 t2
ON t1.Account = t2.Account AND t1.Client = t2.Client
WHERE t1.Account = 111
GROUP BY t1.Account, t1.Client';
$query = $this->db->query($sql);
If you are using MySQL > 5.6 then use the group by function any_value():
t1.Account, t1.Client, ANY_VALUE(t1.Wala), ANY_VALUE(t2.Meron)
To be used with caution since unexpected results may appear if you have multiple rows with different values in the columns "Wala" or "Meron" for the same Account and Client.

Joining two tables in laravel - how to have second table data as a property of result

I have two tables A and B.
Table A:
no name type
1 shoe 1
2 shirt 2
3 book 3
Table B:
type color size
1 red big
2 yellow small
3 blue medium
When I query where A.no === 1 and A.type === 1, I want to get data like:
{
no: 1,
name: 'shoe',
type: 1,
info: {
color: 'red',
size: 'big'
},
}
I tried something like this:
select a.*, b.* from stores a, types b where a.type = 1 and a.type = b.id
and it returns only plain object, I want to get nested data like the above.
I think it can be done using join and doing any other query tricks.
Here's the sql fiddle link I prepared for you.
http://sqlfiddle.com/#!9/3ad910/2
Thanks in advance.
Model TableA:
public function info()
{
return $this->hasOne(TableB::class, 'type', 'type');
}
Model TableB:
public function tableA()
{
return $this->belongsTo(TableA::class, 'type', 'type');
}
The Query:
TableA::with('info')->where(['type' => 1, 'no' => 1])->get();
So the query that you have (although better written using post-1992 query syntax) is all that you need. The rest of the problem is a simple case of rearranging the resulting array. I don't know eloquent/laravel, and I'm embarrassingly bad at rearranging arrays, but here's an example of the kind of thing I mean using plain old php (perhaps someone will be kind enough to write a more apt array transformation)...
<?php
/*
DROP TABLE IF EXISTS table_a;
CREATE TABLE table_a
(no SERIAL PRIMARY KEY
,name VARCHAR(12) UNIQUE
,type INT NOT NULL
);
INSERT INTO table_a VALUES
(1,'shoe',1),
(2,'shirt',2),
(3,'book',3);
DROP TABLE IF EXISTS table_b;
CREATE TABLE table_b
(type SERIAL PRIMARY KEY
,color VARCHAR(12) NOT NULL
,size VARCHAR(12) NOT NULL
);
INSERT INTO table_b VALUES
(1,'red','big'),
(2,'yellow','small'),
(3,'blue','medium');
SELECT a.no
, a.name
, b.*
FROM table_a a
JOIN table_b b
ON b.type = a.type
ORDER
BY a.no;
+----+-------+------+--------+--------+
| no | name | type | color | size |
+----+-------+------+--------+--------+
| 1 | shoe | 1 | red | big |
| 2 | shirt | 2 | yellow | small |
| 3 | book | 3 | blue | medium |
+----+-------+------+--------+--------+
*/
require('path/to/connection/stateme.nts');
$query = "
SELECT a.no
, a.name
, b.type
, b.color
, b.size
FROM table_a a
JOIN table_b b
ON b.type = a.type
WHERE a.no = 1
AND a.type = 1
ORDER
BY a.no;
";
$result = mysqli_query($db,$query) or die(mysqli_error());
$old_array = array();
while($row = mysqli_fetch_assoc($result)){
$old_array[] = $row;
}
$new_array = array();
foreach ($old_array as $row) {
$new_array[]['name'] = $row['name'];
$new_array[$row['no']]['info']['color'] = $row['color'];
$new_array[$row['no']]['info']['size'] = $row['size'];
}
$new_array = array_values($new_array); // reindex
print_r($new_array);
?>
Outputs:
Array
(
[0] => Array
(
[name] => shoe
)
[1] => Array
(
[info] => Array
(
[color] => red
[size] => big
)
)
)
or, json_encoded...
[{"name":"shoe"},{"info":{"color":"red","size":"big"}}]

Combine two SELECT queries together by using value from SELECT in WHERE

id | number
---|--------
1 | null
2 | 1
3 | null
4 | 0
5 | 4
6 | 4
This is what I want to do this in one query. How can I combine both of these queries together?
$id = 4;
SELECT * FROM users WHERE id = $id OR number = $id
// This will return rows 4,5,6
2nd query:
$id = 5;
SELECT * FROM users WHERE id = $id AND id = $numberColumnOfId AND number = $numberOfColumnId;
// This will return rows 4,5,6
$numberColumnOfId is the number of the $id. So if the $id = 5, then the number would be 4. So select rows where ID = 5.
How can I combine both of the SELECT statements together?
Use two queries that you combine with UNION.
The first query gets the rows with the given $id, the second query gets the ones that match via thenumber` column.
SELECT *
FROM users
WHERE id = $id OR number = $id
UNION
SELECT u1.*
FROM users AS u1
JOIN users AS u2 ON u1.number = u2.number OR u1.id = u2.number
WHERE u2.id = $id or u2.number = $id
DEMO

$wpdb MySQL select from main table and join each row with two rows of another table

$referrer is the only defined variable.
main_table holds the relationship between users and referrers. a referrer can have many users.
user_id | referrer
1 | seller
2 | abother seller
3 | another seller
4 | seller
secondary_table holds user_id, meta_key and meta_value with last_name and first_name being meta_keys.
user_id | meta_key | meta_value
1 | first_name | John
1 | last_name | Doe
4 | first_name | Betty
4 | last_name | Boo
I need to merge the following 3 queries
SELECT user_id FROM main_table WHERE referrer = $referrer
SELECT meta_value FROM secondary_table WHERE user_id = $user_id AND meta_key = first_name
SELECT meta_value FROM secondary_table WHERE user_id = $user_id AND meta_key = last_name
into one query so I can use it with $results = $wpdb->get_results, then asort() the $results by last_name to have an alphabetically ordered output and echo $results with a foreach like
foreach ($results as $result) {
echo $result->user_id.' '.$result->first_name.' '.$result->last_name;
}
If $referrer == "seller" the output should look like this:
4 Betty Boo
1 John Doe
How should that single query look like?
Thanks for your help.
You could use this:
select
main_table.user_id,
concat(s1.meta_value, ' ', s2.meta_value) as name
from
main_table left join secondary_table s1
on main_table.user_id = s1.user_id and s1.meta_key = 'first_name'
left join secondary_table s2
on main_table.user_id = s2.user_id and s2.meta_key = 'last_name'
where
referrer = $referrer
I'm joining main_table with secondary_table twice, the first time filtered on the first name, the second time filtered on the last name. Then to get the name you just have to concat the first meta_value with the second.
Its little bit tricky. You can use following query
select m.user_id as new_user_id, s1.meta_value as new_first_name, s2.meta_value as new_last_name from main_table m, secondary_table s1, secondary_table s2 where m.user_id=s1.user_id and m.user_id=s2.user_id and s1.meta_key='first_name' and s2.meta_key='last_name' and m.referrer='seller' order by new_last_name
and then u can do
$results = $wpdb->get_results(...)
foreach ($results as $result) {
echo $result->new_user_id.' '.$result->new_first_name.' '.$result->new_last_name;
}

Does MySQL table row contain two values

I have a table with two columns:
ID1 | ID2
---------
1 | A
3 | V
1 | C
4 | B
5 | Q
1 | S
And I want to be able to find out if any row has, say ID1 = 5 and ID2 = Q , and return a true / false value.
Yes, Of course
SELECT * FROM table where ID1='5' and ID2='Q'
PHP (I am just guessing this backend)
$query = "SELECT * FROM table where ID1='5' and ID2='Q'";
$result = mysql_query($query);
if(mysql_num_rows($result)) { return true; }
else { return false; }
1 means TRUE for mysql
SELECT 1
FROM your_table
WHERE ID1 = 5 AND ID2 = 'Q'
for example this?
SELECT 1
FROM TABLE
WHERE ID1 = 5 AND ID2 = 'Q'
Efficient query for your purpose (faster than other examples):
SELECT 1 FROM table where ID1='5' and ID2='Q' LIMIT 1
PHP sample:
<?php
$query = "SELECT 1 FROM table where ID1='5' and ID2='Q' LIMIT 1";
echo bool(mysql_num_row(mysql_query($query)));
?>