I have two tables,
The first one:
things descriptions
------ ------------
First thing First description
Second thing Second description
Third thing Third description
Fourth thing Fourth description
...
The second one:
id products
-- --------
1 First product
2 Second product
3 Third product
4 Fourth product
...
I need a query to display the first two rows from the first table and then the first row of the second one, then the second two rows from the first table, then the second row of the second one and so on, obtaining this:
things+id prod+descr
--------- ----------
First thing First description
Second thing Second description
1 First product
Third thing Third description
Fourth thing Fourth description
2 Second product
...
How can I do it? Maybe with a UNION? Thank you very much!
Seems to me like the best practice here is to add another column to your first table that is a FK matching the PK of your first table. Would it be acceptable to have data like this? Then retrieve it in a program?
t2.ID t2.prod t1.thing t1.desc
------ ------- -------- -------------
1 first prod first thing first desc
1 first prod second thing second desc
UPDATE: based on your needs
// setup count
$countOuter = 0;
$countInner = 0;
//connect
$mysqli = mysqli_connect(localhost,user,pass,database);
// heres the tricky part you will have to make sure that your
// tables are filled out at a ratio of 2:1 or there could be an
// error thrown
// not sure if this is going to be necessary for your purposes
$sqlTest = "select * from tableOne"
$sqlTest2 = "select * from tableTwo"
$result1 = mysqli_query($mysqli, $sqlTest) or die (mysqli_error($mysqli));
$result2 = mysqli_query($mysqli, $sqlTest2) or die (mysqli_error($mysqli));
$rowsTableOne = mysqli_num_rows($result1);
$rowsTableTwo = mysqli_num_rows($result2);
// check ratio
if(($rowsTableOne / $rowsTableTwo) == 2)
{
while($countOuter < $rowsTableOne)
{
//outer query
$sqlOuter = "select * from tableOne LIMIT 2";
if ($count % 2 == 0) {
$sqlOuter .= " OFFSET ".$count;
}
$result = mysqli_query($mysqli, $sqlOuter) or die (mysqli_error($mysqli));
while($row = mysqli_fetch_array($result, MYSQLI_NUM))
{
echo "<p>".$row[0]." ".$row[1]."</p>";
$countOuter++;
}
$sqlInner = "select * from tableTwo LIMIT 1";
if ($countInner != 1) {
$sqlInner .= " OFFSET ".$countInner;
}
$result = mysqli_query($mysqli, $sqlInner) or die (mysqli_error($mysqli));
while($row = mysqli_fetch_array($result, MYSQLI_NUM))
{
echo "<p>".$row[0]." ".$row[1]."</p>";
$countInner++;
}
}
}
This should give you some general ideas, I did not have time to test it but it should point you in the general direction.
Related
Low level question but, I understand that you can select elements from a table using:
$sql = "SELECT blah FROM TABLE WHERE this = 'something' ";
But when I try to select a specific value from my table, where let's say a user has no tries left so if I try to grab how many tries they have left with:
$sql = "SELECT tries FROM table WHERE user = 'something'";
How would I grab that value specifically if it was 5 or 9? I tried setting a variable equal to something I $sql off my table but it doesn't grab the value.
Edit
I have a database that has a table called Item which contains: id, name, value, and stock of a particular item. If a user wants to order that item I will first check it if's in stock with a function, to see if it is not in stock then a error message is printed, otherwise accept the order.
Extremely primitive since I'm just trying to get grab the stock value first.
$query = $_GET['query']; //id I get from the specified item
echo 'the id is: ' .$query.''; //test purposes
$mysql_handle = mysql_connect($dbhost, $dbuser, $dbpass)
or die("Error connecting to database server");
mysql_select_db($dbname, $mysql_handle)
or die("Error selecting database: $dbname");
$sql1 = "SELECT item_stock FROM chat-db.Item WHERE id = '".$query."'";
echo '' .$sql2. ''; //test purposes
whats the correct way to assign the value from that specific stock to a variable?
If you want to grab rows with a set of possible values you can use 'IN' such as:
Get all columns from users table where users have 5 or 9 tries:
SELECT * FROM users WHERE tries IN('5', '9'); or
If you want to select where the user has no tries left, assuming the tries column is a numeric type you can look for rows with 0 tries:
Get all columns from Item table where stock is 0:
SELECT * FROM db_inv.Item WHERE stock = '0';
Get all columns from users table where tries is 0:
SELECT * FROM users WHERE tries = '0';
As for your php code you should be able to do the following:
$query = $_GET['query']; //id I get from the specified item
echo 'the id is: ' . $query; //test purposes
$mysql_handle = mysqli_connect($dbhost, $dbuser, $dbpass) or die("Error connecting to database server");
$sql1 = "SELECT item_stock FROM chat-db.Item WHERE id = '".$query."'";
$results = mysqli_query($mysql_handle, $sql1);
if (!empty($results) && mysqli_num_rows($results) > 0) {
while($rec = mysqli_fetch_array($results)) {
echo $rec['item_stock'];
}
}
This is what i have right now
What need to happen is that when the query run it should get a record where id will equal next id but if the record does not exist it should grab the next one but when i try and run the query below it runs and gets the last record which is the highest record
To make it clear:
Records in database:
1
5
6
7
8
10
So if the query checks for a record 2 (which is not there) it should get the next highest which is 5 not 10 how would i do that?
$query = "SELECT * FROM images where images >= '$nextid'";
$sql = mysqli_query($conn,$query) or die(mysqli_error($conn));
while($row = mysqli_fetch_array($sql)){
$forwardid = $row['images_id'];
$picname = $row['image_name'];
}
Try this
$query = "SELECT * FROM images where images >= '$nextid' ORDER BY
images_id ASC LIMIT 0 , 1";
Try this:
SELECT *
FROM images
WHERE images_id >= 2
ORDER BY images_id
LIMIT 1;
You can add another iteration that converts your resource into an array and also includes the next ID
$result = mysql_query(" your query ");
$recordset = array(); $i = 0;
while ($row = mysql_fetch_assoc($result))
{
$recordset[$i] = $row;
if ($i > 0) { $recordset[$i-1]['nextid'] = $row['id']; }
$i++;
}
Get the next record
you can try like following. i think it will help you.
select * from images where images_id=
(select Min(images_id) from images where images_id>=2)
N.B: here 2 is your given 'images_id'
You can use this
SELECT MAX(records) FROM images WHERE records < (SELECT MAX(records) FROM images)
take a look at this and run and let me know if you need something different.
I have 2 MYSQL tables and when I pick up dates from table A which contains only 1 column and lets say 10 rows with dates
$result = mysql_query("SELECT * FROM A");
$row = mysql_fetch_assoc($result);
And after I want to UPDATE another table B with using this dates from table A mysql_query("UPDATE B SET something='1' WHERE name='".$row['name']."'")
So i need to update the second table, but its updating just once with first date from table A, and other 9 its ignoring. So my question is, how to make updating of second table with each date from 1 table?
You need to run a the updates in a loop. After executing your query
$result = mysql_query("SELECT * FROM A");
and verifying that it has succeeded (make sure $result is not null), instead of fetching one row, use a loop:
while($row = mysql_fetch_assoc($result)){
// perform calculations & assignments with the $row elements
$result2 = mysql_query("UPDATE B SET something='1'
WHERE name='".$row['name']."'");
if(! $result2){
echo "update failed";
}
// Any other stuff you need to do
}
Alternatively:
If the something in the update is the same for all the rows, you can change your first query to give you a coma-separated string of names:
$result = mysql_query("SELECT CONCAT("'",GROUP_CONCAT(name SEPARATOR "','"),"'")
AS all_names FROM A");
This way, you receive only one row, and you can then use it in your second query:
$result2 = mysql_query("UPDATE B SET something='1'
WHERE name IN (".$row['name'].")");
I'm trying to get the profiles names which are assigned to a specific subcategory
with id=9. When I run the code below, I get the profiles that I want but for some
reason the ORDER BY clause in the foreach loop doesn't sort them by their name
alphabetically. Instead they are ordered in the same way they are ordered inside the
'profiles' field in 'subcategories' table (the IDs for the profiles are comma separated).
For example if in subcategories['profiles'] I have ',5,1,2' the profiles names will be displayed
in the following order:
Profile with ID=5
Profile with ID=1
Profile with ID=2
I'm using the explode() function to get the ID for each profile inside the 'subcategory'
table and then use that ID to retrieve their information from the 'profile' table using
a query inside the foreach loop.
Am I missing anything here? Thanks for your help.
Here's my code:
<?php
$subcategories=mysql_query("select * from subcategories where id='9'");
while ($subcategories = mysql_fetch_array($subcategories))
{
$profiles = $subcategories['profiles'];
$profiles = explode(',', $profiles);
foreach ($profiles as $p)
{
$all_places = mysql_query("select * from profile where id='$p' and active='1' order by name asc");
while ($profile = mysql_fetch_array($all_places))
{
echo $profile['name'];
}
}
}
?>
Well the reason why your results do not order by name is because you are retrieving every profile with a new SQL query in your foreach loop for $profiles. So effectively in your scenario, you will end up with 3 SQL queries that returns 1 profile each. Hence, when the "order by" clause is declared, it orders by name within each query, which only contains 1 result each.
does using an IN statement work for you? Eg.
<?php
$subcategories=mysql_query("select * from subcategories where id='9'");
while ($subcategories = mysql_fetch_array($subcategories))
{
//i assume $subcategories['profiles'] are integers separated by comma as mentioned
$profiles = $subcategories['profiles'];
$all_places = mysql_query("select * from profile where id IN ($profiles) and active='1' order by name asc");
while ($profile = mysql_fetch_array($all_places))
{
echo $profile['name'];
}
}
?>
I want to display four (4) items'name from these id:
Can I do like this?
SELECT item_name from items WHERE item_id IN ('001', '012', '103', '500')
or
SELECT item_name from items WHERE item_id = '001' or item_id = '012' or item_id = '103' or item_id = '500'
IN RESPONSE TO ALL ANSWERS
Well, most of the answers said it works, but it does not really work. Here is my code:
$query = "SELECT `item_name` from items WHERE item_id IN('s001','a012','t103','p500')";
$result = mysql_query($query, $conn) or die (mysql_error());
$fetch = mysql_fetch_assoc($result) or die (mysql_error());
$itemsCollected = $fetch['item_name'];
echo $itemsCollected;
The item_id is alphanumeric.
You can do either one, but the IN query is much more efficient for this purpose for any large queries. I did some simple testing long ago that revealed it's about 10 times faster to use the IN construct for this. If you're asking if the syntax is correct then yes, it looks fine, other than missing semi-colons to complete the statement.
EDIT: It looks like the actual question you were asking was "why do these queries only return one value". Well, looking at the sample code you posted, the problem is here:
$fetch = mysql_fetch_assoc($result) or die (mysql_error());
$itemsCollected = $fetch['item_name'];
echo $itemsCollected;
You need to loop through and iterate until there are no more results to be fetched, as Pax pointed out. See the PHP manual page for mysql_fetch_assoc:
$sql = "SELECT item_name from items WHERE item_id IN('s001','a012')";
$result = mysql_query($sql);
if (!$result) {
echo "Could not successfully run query ($sql) from DB: " . mysql_error();
exit;
}
if (mysql_num_rows($result) == 0) {
echo "No rows found, nothing to print so am exiting";
exit;
}
// While a row of data exists, put that row in $row as an associative array
// Note: If you're expecting just one row, no need to use a loop
// Note: If you put extract($row); inside the following loop, you'll
// then create $userid, $fullname, and $userstatus
while ($row = mysql_fetch_assoc($result)) {
echo $row["userid"];
echo $row["fullname"];
echo $row["userstatus"];
}
mysql_free_result($result);
Yes, both those should work fine. What's the actual problem you're seeing?
If, as you say, only one record is being returned, try:
select item_name from items order by item_id
and check the full output to ensure you have entries for 001, 012, 103 and 500.
If both those queries only return one row, I would suspect not.
If they all do exist, check the table definitions, it may be that the column is CHAR(4) and contains spaces for the others. You may have genuinely found a bug in MySQL but I doubt it.
After EDIT:
This is a perl/mysql problem, not an SQL one: mysql_fetch_array() returns only one row of the dataset at a time and advances a pointer to the next.
You need to do something like:
$query = "SELECT item_name from items WHERE item_id IN('s001','a012')";
$result = mysql_query($query, $conn) or die (mysql_error());
if (mysql_num_rows($result) == 0) {
echo "No rows found, nothing to print so am exiting";
exit;
}
while ($row = mysql_fetch_assoc($result)) {
echo $row["item_name"];
}
Your ID field must be set to auto increment, i guess. i had problems with that once and i changed the auto increment to int. in the IN field if you pass the parameters to match against the auto increment variable you get back only the first parameter, the remaining generates an error.
Use mysql_fetch_assoc to get the query and assign the values from mysql_fetch_assoc query into a an array. Simple as that
$i=0;
$fullArray = array();
$query = mysql_query("SELECT name FROM users WHERE id='111' OR id='112' OR id='113' ")or die(mysql_error());
while($row = mysql_fetch_assoc($query)){
foreach ($row as $value) {
$fullArray[$i] = $value;
}
$i++;
}
var_dump($fullArray);
echo $fullArray[0]."<br/>".$fullArray[1]."<br/>".$fullArray[2];`
You could also use the mysql_num_rows function to tell you how many rows your query retrieved and then use that result to increment a for loop. An example.
$num_rows=mysql_num_rows($query_results);
for ($i=0; $i <$num_rows ; $i++) {
$query_array[]=mysql_fetch_assoc($query_results);
}