quick question!
how do i perform 2 selects with PDO and run them through the same loop ?
$sql1 = $db->query("SELECT * FROM produkts");
$sql2 = $db->query("SELECT * FROM buyers");
$sql1->setFetchMode(PDO::FETCH_ASSOC);
$sql1->setFetchMode(PDO::FETCH_ASSOC);
while($row = $stmt->fetch() && $row1 = $stmt1->fetch()){
Something to be displayed
}
This obviously doesn't work, and i have no clue how to make it work.
how is this performed ??
Assuming something like:
Buyers Produkts
---------- ---------
buyerid .-produktid
produktid-' [...]
[...]
You can use:
SELECT b.*, p.*
FROM buyers b
LEFT JOIN produkts p
ON p.produktid = b.produktid
That will go through and query each buyers then for every produktid supplied and found in the produkts table, it will be joined in the result. You can also reverse it it bring buys in on products: For example:
SELECT p.*, b.*
FROM produkts p
LEFT JOIN buyers b
ON b.produktid = p.produktid
Which will bring in the buyers details based on a produkts match.
This is going by what you've told me, that both tables share a produktid column. I still don't know what you're after or know any more about the table schema, so if I'm off let me know (and provide more information).
Related
I am trying to make a "recipe" system inside a game. The player can own a company and craft items in there.
I currently fetch the recipes per company type but I don't know how to write the query in a way that I can also fetch the item names and images if the item_id is not empty.
This is working:
SELECT a.recipe_id,
a.item1_id,
a.item1_uses,
a.item2_id,
a.item2_uses,
a.item3_id,
a.item3_uses,
a.item4_id,
a.item4_uses,
a.item5_id,
a.item5_uses,
a.newitem_id,
a.newitem_uses,
a.craft_description,
a.craft_button
FROM
company_recipes AS a,
company_types AS b
WHERE
a.type_id = b.type_id
AND
b.type_id = '".$type."';
"
A recipe can contain for example two items needed to craft something new, but it could also be 5. So if it's only 2, I only want to fetch the img, name of these 2 and the rest can be skipped.
I have a different table store_items that contains the img and name of the item. I was thinking something along the lines of an IF ELSE or CASE WHEN inside the query, but I'm not sure how I'd do that.
Something like: SELECT c.img, c.name FROM store_items AS c IF a.item1_id is not NULL.
I feel like I'm close to the solution, but missing the last step.
Thanks for the tips #jarlh, I've changed the code and came to this result. If you have any more tips to do it better I'm happy to listen. (I'm still a junior and thought myself by trial and error, so I might not have the best solutions at times... Which is why tips are highly appreciated).
SELECT cr.recipe_id,
cr.item1_id,
cr.item1_uses,
si1.name,
si1.img,
cr.item2_id,
cr.item2_uses,
si2.name,
si2.img,
cr.item3_id,
cr.item3_uses,
si3.name,
si3.img,
cr.item4_id,
cr.item4_uses,
si4.name,
si4.img,
cr.item5_id,
cr.item5_uses,
si5.name,
si5.img,
cr.newitem_id,
cr.newitem_uses,
si_new.name,
si_new.img,
cr.craft_description,
cr.craft_button
FROM
company_recipes AS cr
INNER JOIN company_types AS ct ON cr.type_id = ct.type_id
LEFT JOIN store_items AS si1 ON cr.item1_id = si1.item_id
LEFT JOIN store_items AS si2 ON cr.item2_id = si2.item_id
LEFT JOIN store_items AS si3 ON cr.item3_id = si3.item_id
LEFT JOIN store_items AS si4 ON cr.item4_id = si4.item_id
LEFT JOIN store_items AS si5 ON cr.item5_id = si5.item_id
LEFT JOIN store_items AS si_new ON cr.newitem_id = si_new.item_id
WHERE
ct.type_id = '".$type."';
I'm basically fetching everything now and handle the NULLs in the php code now.
Without seeing more info its had to see what you are trying achieve but you could start by using the the users inpute of the game to determine what data is first required before futher filtering. Try this:
Declare #Value int
set #Value = #User_input --- uses what ever the game user will
SELECT
a.recipe_id,
a.item1_id,
a.item1_uses,
a.item2_id,
a.item2_uses,
a.item3_id,
a.item3_uses,
a.item4_id,
a.item4_uses,
a.item5_id,
a.item5_uses,
a.newitem_id,
a.newitem_uses,
a.craft_description,
a.craft_button
--- you can insert more columns but i stopped here as i dont know what data you have in the other tables.
FROM
company_recipes a
INNER JOIN company_types b ON a.type_id = b.type_id
INNER JOIN store_items c ON c.type_id = b.type_id
WHERE
b.type_id = #Value; --- '".$type."';
I am trying to only show unique userIds (userIds are (0,1,2,3,4,5,6,7,8,9 etc...) for the query I am running. I tried using DISTINCT in my query, but it only shows me unique values of the rows that have 2 or more of the same userId.
Is there a way I can use php to only show the unique values. My weak points are arrays and it makes it more complicated because its using data from a MySQLi query.
Example right now I have with the query now (lets say its GROUP BY rentPaid DESC and the rent total is 800.00 for all users):
userID rentPaid rentMonth
2--------800.00------April
1--------500.00------April
3--------400.00------April
3--------400.00------April
1--------200.00------April
1--------100.00------April
Example desired output:
userID rentPaid rentMonth
2--------800.00------April
1--------500.00------April
3--------400.00------April
Can I do this with MYSQL because I tried DISTINCT and it wouldn't work, how about PHP?
Query:
SELECT
properties.*,
leases.*,
users.userId, users.primaryPhone,
CONCAT(users.userFirstName,' ',users.userLastName) AS user,
admins.adminName, payments.*
FROM
properties
LEFT JOIN leases ON properties.propertyId = leases.propertyId
LEFT JOIN assigned ON properties.propertyId = assigned.propertyId
LEFT JOIN admins ON assigned.adminId = admins.adminId
LEFT JOIN users ON properties.propertyId = users.propertyId
LEFT JOIN payments ON properties.propertyId = payments.propertyId
WHERE
payments.rentMonth = '$currentMonth' AND
payments.rentYear = '$currentYear'
Edit: Please excuse my formatting, this is my first post.
Edit: Added query....its long, but works lol. I only want unique userIds (no double or triple userIds etc...)
I suspect this is what you want:
SELECT userID, MAX(rentPaid) AS maxRentPaid, rentMonth
FROM yourTable
WHERE rentMonth = "April"
GROUP BY userID
ORDER BY maxRentPaid
I am trying to list down all the students who dont pay their dues between two date ranges. I first select all the student ids from fee table and then store it in a variable and then compare these ids with student table to list down all non paid students. But my problem is it works only on last id. Let say if i get student id, 1 and 2 then query works only on student id 2. Here is the code.
$query = mysql_query("SELECT student_id,created FROM fee WHERE DATE(created) between '$sqldate1' AND '$sqldate2'");
while($rows = mysql_fetch_array($query)) {
$students = $rows['student_id'];
//echo $students;
$link = mysql_query("SELECT fee.class_id,fee.section_id,fee.student_id,fee.section_group,
fee.student_fee,fee.test_fee,fee.other_charges,fee.created,fee.fee_month,
class.class_id,class.class_name,section.section_id,section.section_name,student.id,
student.student_name FROM fee LEFT JOIN class ON(fee.class_id=class.class_id)
LEFT JOIN section ON(fee.section_id=section.section_id)
LEFT JOIN student ON(fee.student_id=student.id) WHERE student.id !='$students'")
or die(mysql_error());
$num = mysql_num_rows($link);
}
You must specify the table name on the join condition as mentioned below
$link = mysql_query("SELECT fee.class_id,fee.section_id,fee.student_id,fee.section_group,
fee.student_fee,fee.test_fee,fee.other_charges,fee.created,fee.fee_month,
class.class_id,class.class_name,section.section_id,section.section_name,student.id,
student.student_name FROM fee LEFT JOIN class ON(fee.class_id=class.class_id)
LEFT JOIN section ON(fee.section_id=section.section_id)
LEFT JOIN student ON(fee.student_id=student.id) WHERE DATE(fee.created) between '$sqldate1' AND '$sqldate2'")
You are iterating over every student_id from your initial query, and running your second query using a different, single student each time. Since you are overwriting $students, $link, and $num each iteration without storing them somewhere, that data is lost and you will be left with whatever the last iteration of your loop happened to be.
You need to first construct a list of all student_ids which you wish to check against, then use that in a comparison in your second query (which needs to be outside of the while loop).
$students is being overwritten in your while loop with each new student id, leaving it with only the last one. Make $students an array:
$students[] = $row['student_id'];
And changr the second query:
WHERE student.id NOT IN (".implode(",", $students).")
You can just have one query:
SELECT fee.class_id,fee.section_id,fee.student_id,fee.section_group,
fee.student_fee,fee.test_fee,fee.other_charges,fee.created,fee.fee_month,
class.class_id,class.class_name,section.section_id,section.section_name,student.id,
student.student_name FROM fee LEFT JOIN class ON(fee.class_id=class.class_id)
LEFT JOIN section ON(fee.section_id=section.section_id)
LEFT JOIN student ON(fee.student_id=student.id) WHERE student.id NOT EXISTS (SELECT student_id,created FROM fee WHERE DATE(created) between '$sqldate1' AND '$sqldate2');
Here's my problem: I'm making a crafting system for a game, and I already have my database filled with information for resources required to craft items.
Here are what my relevant tables look like:
table #edible_resources
(edible_resource_id, edible_resource_name, hunger_points, degeneration_id)
table #edible_ground
(id, resource, amount, location)
table #req_crafting_edible
(req_crafting_edible_id, edible_resource_id, req_resource_amount, created_item_id)
table #items
(item_id, item_name, degeneration_id, is_grounded, is_stackable, can_equip, can_edit)
What I want to do is -only- echo out the craftable item's name if, and only if -all- required resources (and their required amounts) are on the ground in the location of the character.
I have a query that comes close:
SELECT items.item_name, items.item_id FROM items
INNER JOIN req_crafting_edible
ON req_crafting_edible.created_item_id = items.item_id
INNER JOIN edible_ground
ON edible_ground.resource = req_crafting_edible.edible_resource_id
AND edible_ground.amount >= req_crafting_edible.req_resource_amount
WHERE edible_ground.location = $current_location
GROUP BY items.item_name
ORDER BY items.item_name
But this shows me craftable items regardless if I have ALL the required items in the area. It shows me items as long as I have -one- of their required resources.
Is there a way to only show the name of a craftable item only if I have -all- the required resources (and their amounts) in edible_ground where location = $current_location?
For more information on what I've tried:
$get_char = mysql_query("SELECT current_char FROM accounts WHERE account_id ='".$_SESSION['user_id']."'");
$current_char = mysql_result($get_char, 0, 'current_char');
$get_loc = mysql_query("SELECT current_location FROM characters WHERE character_id = $current_char");
$current_location = mysql_result($get_loc, 0, 'current_location');
//---------------------------------------------------------------COOKED FOOD
$get_food = mysql_query("SELECT items.item_name, items.item_id FROM items
INNER JOIN req_crafting_edible
ON req_crafting_edible.created_item_id = items.item_id
INNER JOIN edible_ground
ON edible_ground.resource = req_crafting_edible.edible_resource_id
AND edible_ground.amount >= req_crafting_edible.req_resource_amount
WHERE edible_ground.location = $current_location
GROUP BY items.item_name
ORDER BY items.item_name");
while ($food = mysql_fetch_array($get_food)){
echo $food['item_name'].'<br>';
}
This returns:
Baked Fish
Charred Fish
Fish Soup
Glazed Berry
Cake
Grilled Fish
Sashimi
Seafood Soup
Sushi
Udon
On the ground:
1 fish
1 honey
Even though fish soup, berry cake, udon etc needs much more than just the one fish that's in the area.
Can anyone help me figure this out? I'd be forever grateful; I've spent a few days already trying to myself. Please?
And before anyone says anything, I know I need to start using mysqli; unfortunately I didn't even realize it existed when I started to make the game (and learn PHP at the same time months ago), so I'll have to painfully go back and change it all in an update.
You want a HAVING clause to check the count of the records you are grouping through the INNER JOINs.
HAVING count(*) = (
SELECT count(*)
FROM req_crafting_edible
WHERE req_crafting_edible.created_item_id = items.item_id
)
Edit:
So basically you need to know two pieces of information:
How many different resources are required
Do each of those resources have the required amounts
The first is solved by the sub query above.
Your query as-is satisfies the second point but only for 1 resource.
HAVING basically does some special magic on your group clause. HAVING count(*) means there are X records being grouped together. Because of how the join works, you will have 1 item.name for each resource. The sub select gives you the count of how many different resources, and therefore grouped records, are needed for that item. Comparing that sub query with the count(*) of the grouping ensures you have all the needed resources.
And here is the final query, modifying your code above:
SELECT items.item_name, items.item_id
FROM items
INNER JOIN req_crafting_edible
ON req_crafting_edible.created_item_id = items.item_id
INNER JOIN edible_ground
ON edible_ground.resource = req_crafting_edible.edible_resource_id
AND edible_ground.amount >= req_crafting_edible.req_resource_amount
WHERE edible_ground.location = $current_location
GROUP BY items.item_name
HAVING count(*) = (
SELECT count(*)
FROM req_crafting_edible
WHERE req_crafting_edible.created_item_id = items.item_id
)
ORDER BY items.item_name
You only actually want the data from the items table, right? If so I would move to using an exists model:
SELECT I.item_name, I.item_id FROM items I
WHERE NOT EXISTS
(SELECT created_item_id
FROM req_crafting_edible R
WHERE R.created_item_id = I.item_id
AND NOT EXISTS
(SELECT G.resource
FROM edible_ground G
WHERE G.resource = R.edible_resource_id
AND edible_ground.location = $current_location
AND G.amount >= R.req_resource_amount))
ORDER BY I.item_name
I don't have your database to check this, but the logic goes like this:
Find the items that don't have any unsatisfied requirements.
Find the unsatisfied requirements for the current item. (IE. Find
requirements that don't have resources on the ground)
Find the edible resources that match the current requirement, are at
this location, and have enough.
I don't work in mysql as much at the moment, but let me know if this doesn't work.
SELECT * FROM dog WHERE (SELECT calluser FROM jos_users WHERE `user_id`='".$cid."')=Subcode
$cid is the identifier in jos_users, which tells us which users we're fetching data about
The data I want to fetch is within "dog", and calluser is the identifier between the two (which tells us who's dogs are who's)
I need to be able to call only the dogs relevant to the user in question, but it also has to be performed in one query. Can anyone help? Much appreciated.
You need to use joins.
Read this tutorial: http://www.tizag.com/mysqlTutorial/
Your query should look something like this:
$cid = mysql_real_escape_string($_GET['cid']);
$query = "SELECT d.* FROM dog d
INNER JOIN jos_users ju ON (d.user_id = ju.id)
WHERE ju.id = '$cid' ";
If I got you right (and the id column in the dog-table links to the calluser column in the jos_user-table) the query should be
SELECT d.* FROM dog AS d JOIN jos_user AS u ON d.id = u.calluser WHERE u.user_id = '$cid'
If not please explain your data structure in more detail (maybee small ER diagram).