I am a beginner at SQL. I am trying to write the following statement, but where user is in group (so where group_members.user_id = $_SESSION['user_id']).
SELECT `group_name`, `group_description` FROM `groups`
How do I write this sort of query that relates values from two different tables? Sorry if I haven't explained this well.
EDIT: When I use the query provided by Matthew Haugen, I seem to have the following difficulty: only one set of results is returned in an array.
This is my code for the function that does the query:
function group_summary(){
$sql = secure_mysqli("SELECT `group_name`,`group_description` FROM `groups` WHERE `group_id` IN (SELECT `group_id` FROM `group_members` WHERE `user_id` = ?)", array($_SESSION['user_id']), "i");
$groups = $sql;
return $groups;
}
And this is secure_mysqli:
function secure_mysqli($query, $values, $datatypes) {
global $link;
$stmt = mysqli_prepare($link, $query);
if($stmt !== false){
if(is_array($values)){ foreach ($values as &$value) $ref_values[] = &$value;
call_user_func_array("mysqli_stmt_bind_param", array_merge(array($stmt, $datatypes), $ref_values));
mysqli_stmt_execute($stmt);
return #mysqli_fetch_assoc(mysqli_stmt_get_result($stmt));
}}}
It sounds like you want either this
SELECT * FROM Groups
WHERE Groups.Id IN (SELECT GroupId FROM Group_Members WHERE User_Id = #userid)
Or this
SELECT * FROM Groups
INNER JOIN Group_Members ON Groups.Id = Group_Members.GroupId
WHERE Group_Members = #userid
You will have to perform what is called a JOIN, it depends on what type you want, see here.
So you can do something like the following
SELECT A.GROUP_NAME
, B.GROUP_DESCRIPTION
FROM TABLE1 A
JOIN TABLE2 B
ON A.UNIQUE_KEY = B.UNIQUE_KEY
WHERE GROUP_MEMBERS.USER_ID = $_SESSION['USER_ID']
Related
I have a table called payment plan which has this different fields.
I wrote a query to get this rows but I need to modify the query in a way that when I give it a criteria that the amount is 80, which comes from a input field in the html it will only show me one field, from the table, if a I write the amount is 90 it still should show me one table but if I write the amount is 160 or 160 + it should show me both the table. This amounts are basically the CAPITAL_PAYMENT of the table. But I am not sure how to write the query. I wrote this
SELECT c.* , a.Interest
FROM investment a
inner join money_offer b
on a.ORIG_ID = b.investment_orig_id and b.UPDATE_DT is null
inner join payment_plan c
on c.offer_orig_id = b.ORIG_ID and c.UPDATE_DT is null
WHERE a.ORIG_ID = 21 and
a.Owner = 533 and
a.UPDATE_DT is null;
Now I get two rows but depending on amount, if 90, I should get 1 row but I am not sure where do I write it or how.
This amount is basically coming from codeigniter function if it helps here is the code.
public function getLoansBorrowedData($id, $orig_id , $amount){
$query = 'SELECT c.* , a.Interest , d.symbol
FROM investment a
inner join money_offer b
on a.ORIG_ID = b.investment_orig_id and b.UPDATE_DT is null
inner join payment_plan c
on c.offer_orig_id = b.ORIG_ID and c.UPDATE_DT is null
inner join currency d
on c.currency = d.ID
WHERE a.ORIG_ID = '.$orig_id.' and
a.Owner = '.$id.' and
a.UPDATE_DT is null' ;
$query = $this->db->query($query);
/* Return either found rows or false. */
if($query->num_rows() > 0){
$result = $query->result();
return $result;
}
else {
return false;
}
}
Hi, I need a zf2 join query that fetches only the latest row(by id DESC) from the second table. I have written an sql query and it works.
SELECT st1.customer_id,
st1.id
FROM status st1
inner JOIN
(
SELECT max(id) MaxId, customer_id
FROM status
GROUP BY customer_id
) st2
ON st1.customer_id = st2.customer_id
AND st1.id = st2.MaxId
But I need this query at zend framework 2 table gateway format. Please help.
use Zend\Db\Sql\Select;
use Zend\Db\Sql\Expression;
$sql = new Select ();
$sql->columns(["customer_id", new Expression ("max(id) AS MaxId")])
->from ('status')
->group('customer_id');
$outer = new Select ();
$outer->columns (['customer_id', 'id'])
->from (['st1' => 'status'])
->join (['st2' => $sql],
'st1.customer_id = st2.customer_id AND st1.id = st2.MaxId', []);
I want to be able to use one of the items I am selecting further down in my sub query.
As you can see in this example I have set the "variable" in question as 100 but in reality this is going to be a dynamic number so I will need to be able to access it in the subquery.
INSERT INTO users_friends (userId, friendId)
SELECT 77, id as noob
FROM users WHERE email = 'a#g.com'
AND
NOT EXISTS (SELECT * FROM users_friends
WHERE userId = 77 and friendId = noob)
LIMIT 1
I'm not completely sure I understand your question, but NOT EXISTS works just like LEFT JOIN and IS NULL. So I think this will work:
SELECT 77, #noob
FROM users u
JOIN (SELECT #noob:= 100) r
LEFT JOIN users_friends uf on u.userid = uf.userid and uf.friendid = #noob
WHERE email = 'a#g.com'
AND uf.userid IS NULL
And here is the SQL Fiddle.
I think the safest approach is to define these in a subquery. I typically give this the alias of const:
INSERT INTO users_friends (userId, friendId)
SELECT const.userId, const.noob
FROM users cross join
(select 77 as userId, 100 as noob) const
WHERE email = 'a#g.com' AND
NOT EXISTS (SELECT *
FROM users_friends
WHERE userId = const.userId and friendId = const.noob
)
LIMIT 1
I am concerned about SGeddes's approach, because it relies on the correct evaluation of variables outside the scope of the query. This might work in this case, but I prefer a solution where the query does not rely on outside variables. By the way, this should also work in any database, and is not MySQL-specific.
EDIT
I would recommend changing your table structure.
CREATE TABLE users_friends(
userid int,
friendid int,
primary key (userid, friendid)
);
CREATE TABLE users (
userid int primary key,
email varchar(100),
name VARCHAR (100),
index (email,name)
);
INSERT INTO users VALUES (1, 'a#g.com', 'noob'), (2,'b#g.com', 'Joe');
INSERT INTO users_friends (userId, friendId)
VALUES (2, (SELECT userId
FROM users
WHERE email = 'a#g.com'
AND name = "noob"
AND NOT exists (SELECT * FROM users_friends as uf
JOIN users as u
ON u.userid = uf.userid
where uf.friendid = 2 AND name = "noob"
)
)
);
SQL FIDDLE DEMO
Try this:
<?php
function select_query ($userid,$friendname, $email){
$host = "host";
$user = "username";
$password = "password";
$database = "database name";
// open connection to databse
$link = mysqli_connect($host, $user, $password, $database);
IF (!$link){
echo ("Unable to connect to database!");
}
ELSE {
//Is someone registered at other conference from table registration
$query = " INSERT INTO users_friends (userId, friendId)
VALUES (".$userId.", (SELECT userId
FROM users
WHERE email = '".$email."'
AND name = '".$friendname."'
AND NOT exists (SELECT * FROM users_friends as uf
JOIN users as u
ON u.userid = uf.userid
where uf.friendid = ".$userId." AND name = '"$friendname"'
)
)
)";
$result = mysqli_query($link, $query);
return $query;
return $result;
}
mysqli_close($link);
}
echo select_query(1,noob,'a#g.com');
?>
Like I mentioned above I not sure what you mean. If you mean dynamic in the sense that you can change the value of the variable this might help. In your previous posts you used PHP. So, my guess is that your are using PHP.
INSERT INTO users_friends (userId, friendId)
SELECT 77, id
FROM users WHERE email = 'a#g.com'
AND
NOT EXISTS (SELECT * FROM users_friends
WHERE userId = 77 and friendId = (SELECT id
FROM users WHERE email = 'a#g.com'))
LIMIT 1
I have two tables: table_1: item_id, name ... table_2: image_id, item_id, url
The following function retrieves the 'urls' of the items with the '$name' that is passed in. I first need to get the 'item_id' from table_1 to use in the query. I only need to return the 'url's from table_2.
It currently works fine, but I feel it could be streamlined to be done in one query with a JOIN rather than two separate queries. I've tried using different 'JOIN's to make it work but I can't seem to get it right.
Here's the function as it stands now with the two queries...
function get_items( $name ) {
global $wpdb;
$sql1 = "SELECT `item_id` FROM `table_1` WHERE `name` = '$name'";
$results1 = $wpdb->get_var( $sql1 );
$sql1 = "SELECT `url` FROM `table_2` WHERE `item_id` = '$results1'";
$results2 = $wpdb->get_results( $sql1, ARRAY_A );
return $results2;
}
and here is the 'JOIN' that I tried implementing, but was unsuccessful (I've also switched it around and did a 'LEFT/RIGHT JOIN' as well resulting in the same result) ...
$sql1 = "SELECT `table_2`.`url`
FROM `table_2`
INNER JOIN `table_1`
ON `table_2`.`item_id` = `table_1`.`item_id`
WHERE `table_1`.`item_id` = '$name'";
Any advice on combining these two queries?
The problem with your query is this WHERE table_1.item_id = '$name', it should be the name not the item_id
SELECT b.url
FROM table1 a
INNER JOIN table2 b
ON a.item_id = b.item_id
WHERE a.name = '$name'
select url from table_2 where item_id IN (select item_id from table_1 where name = $name )
I have no idea if this is possible but is there a way in MySQL to produce a single query where the multiple results of a one to many table join can be set as an array on a key of the result for the one item?
I realise that question isn't very clear so I'll explain what I'm after further:
Firstly, I'm currently using implicit joins and would like to learn more on explicit joins (of which I currently know very little), perhaps these could provide the answer I'm looking for?
For example given two tables:
CREATE TABLE `a` (
`id_a` int(11) NOT NULL AUTO_INCREMENT,
`a_column1` varchar(255) NOT NULL,
...
PRIMARY KEY (`id_a`)
)
CREATE TABLE `b` (
`id_b` int(11) NOT NULL AUTO_INCREMENT,
`id_a` int(11) NOT NULL,
`b_column1` varchar(255) NOT NULL,
...
PRIMARY KEY (`id_b`)
)
Where table b has many entries related to a single entry in table a.
If I were to run the following query:
SELECT a.*, b.* FROM a, b WHERE b.id_a = a.id_a AND a.id_a = x;
I would get an array with multiple entries with the data of the single item id x repeated. What I actually want is a single row returned from table a with a key defined as b which contains an array of the multiple matching entries from table b. I suspect that this is not possible with a query alone, but it would be great if it was. Currently I am doing the following in PHP (where $this->_db is a Zend Framework database adapter). This runs a lot of queries!:
$query = "SELECT * FROM a WHERE id_a = ?";
$items = $this->_db->fetchAll($query, $id);
foreach($items as $key => $item) {
$query = "SELECT * FROM b WHERE id_a = ?";
$items[$key]['b'] = $this->_db->fetchAll($query, $item['id']);
}
Alternatively I can use my original join query and post process, which I suspect is more efficient, but means I need to explicitly copy over the columns I need (a pain and far from elegant):
$query = "SELECT * FROM a, b WHERE a.id_a = b.id_a AND a.id_a = ?";
$items = $this->_db->fetchAll($query, $id);
$output = array('a_column1' => $items[0]['a_column1'], etc...);
$output['b'] = array();
foreach($items as $item) {
$b = array('b_column1' => $item['b_column1'], etc...);
$output['b'][] = $b;
}
Your query that uses implicit JOIN:
SELECT a.*
, b.*
FROM a, b
WHERE b.id_a = a.id_a
AND a.id_a = x
With explicit JOIN:
SELECT a.*
, b.*
FROM a
JOIN b
ON b.id_a = a.id_a
WHERE a.id_a = x
One way to have the data in one query is to use the GROUP_CONCAT() function. But it may not be in a format you can use:
SELECT a.*
, GROUP_CONCAT( b.id_b
ORDER BY b.id_b ASC
SEPARATOR ','
) AS b_ids
, GROUP_CONCAT( b.b_column1
ORDER BY b.id_b ASC
SEPARATOR ','
) AS b_column1s
, ... --- etc
FROM a
JOIN b
ON b.id_a = a.id_a
WHERE a.id_a = x
GROUP BY a.id_a
You're probably looking for an ORM (object-relational mapper), which would handle associations between objects and would be able to return one A object containing an array of B objects.
See Good PHP ORM Library?
Using explicit joins, the query would look like this:
SELECT a.*, b.* FROM a inner join b on b.id_a = a.id_a where a.id_a = x;