I have two tables. company_details and company_specials. Each company_details can have multiple specials. I display the company details at http://eurothermwindows.com/ed/admin.php
The first row and fourth row that has the 0 in the active column is from company_details and the rows below are from company_specials.
Currently the code allows for dynamic modification of the company_details rows as denoted by the compid in that table. However i would like to have the rows below it to be dynamically modified as well but it's using the same compid and i'm not sure how to separate them in the code.
Code below is the code being generated for the company_specials. I need a way to uniquely identify each row and be able to modify it.
http://pastebin.com/RAe9iwAP
Could somebody provide some guidance please? I'm thinking that i would probably need to uniquely identify each of the specials within the company_specials or set some sort of pointers?
Add unique ids to your db tables and output hidden text fields with each record to indicate it table origin and its id. this will allow the code to know which table had which row updated or deleted. inserting new records can be accomplished by offering a blank record of each type at the end of each group, so there would be one blank specials record at the end of each group and one blank company record at the end of the table.
Put a unique name on each input field of the form name='comp[<?php echo $comp_id?>][<?php echo $comp_field_name?>]' and name='spec[<?php echo $spec_id?>][<?php echo $spec_field_name?>]' so that when the table is posted, PHP will see two arrays, $comp and $spec. You can loop over these with
foreach ($comp as $id=>$row)
{
}
and loop over each $row to build an SQL update or insert statement with
foreach ($row as $fld=>$val)
{
}
Seems you're on the right track. You will indeed need to identify the rows uniquely. You could add a unique id to your company_specials table and use that. Or use some other combination of attributes that's unique to each row in your company_specials table (e.g. concatination of compid & specdate). Whatever fits your information-structure. I would advise to just add a unique id to your specials table.
Be sure to also add that unique-constraint to your database-system to prevent invalid data from being entered.
Related
my database is structured as below
at present the character, groups and vault tables all have data. The games tables is empty however.
Is it possible to write an inner join on the games table that will allow for a php search box to get data from the other three tables even though the games table has no data in it?
Is there another way of doing this that I might not know about?
For example I want to write a php search script for a webpage that searches on the games tables. If a user enters 'Allistair Tenpenny', it will pull the data from the characters table and display it in the search page with the characters name and their history, same with if some one searches a vault it will display the data from the vaults table.
From what I have read of inner joins the data on each joined table must match for it to display. Is there another way to approach this?
No inner join is necessary to get the data you want. You can simply use php to use SQL to search the appropriate table based on the user input.
If there are multiple search fields on your page, just name the submit buttons differently, then have PHP check for the existence of each submit button's POST data from the form, then perform the appropriate search. An example form might be:
<form action="" method="post">
Search Character Name:<input type="text" name="charactername">
<input type="submit" name="charsubmit" value="Search">
</form>
<form action="" method="post">
Search Vault Name:<input type="text" name="vaultname">
<input type="submit" name="vaultsubmit" value="Search">
</form>
Your PHP code can then be structured as:
if (isset($_POST['charsubmit']))
{
$stmt = $db->prepare("SELECT * FROM character_table WHERE character_name = ':mydata'");
$stmt->bindParam(':mydata',$_POST['charactername']);
}
elseif (isset($_POST['vaultsubmit']))
{
$stmt = $db->prepare("SELECT * FROM vault_table WHERE vault_name = ':mydata'");
$stmt->bindParam(':mydata',$_POST['vaultname']);
}
$stmt->execute();
Using prepared statements like this is a good way to prevent SQL injection attacks, thus ensuring user entered data is NEVER put directly into a SQL statement.
Think about it yourself. There should be no redundant information in normalized relative database. All the data tables have a column history. It should not have redundant data, which you could use to identify rows in other tables, but a description of the record set in the own table. We don't know, what vault_number is for. All other tables might be connected to the vault table directly depending on your data structure. Only you know, what your intention building this structure has been.
Further more you have connected games to groups by a redundant column with the group_name. You should avoid any redundancy and give the groups an id. Then connect it to games by a foreign group_id key. Imagine what will happen, when there are 100 games in a group and you decide to rename a group or just want to correct a typo.
Instead of joining the tables why not try to add them to an array?
create an array with the elements you need to display (don't forget to add the same number of elements from all tables (not 3 from 1 table and 4 from the other)
query the first table and use add it to the array
query the the second table and add it to the array
continue adding the tables you need
display the array
Edit:
The array could consist of 4 elements:
vault_number
name
history
type (table it's comming from)
example query would be:
select vault_number, charactor_name as name, history, 'charactor' as type from charactor
select vault_number, group_name as name, history, 'group' as type from groups
You just continue adding this to your array and you can then display all results
Take into consideration what Quasimodo's clone explained about your db normalization and the approach given by Sgt AJ could go a long way.
I have been working on my "administrative" webpage for a while now, almost finished. Just need a little help with one last thing;
I want to get a value (ID) from a table posted as Yes if the ID is found, but no if it isn't.
Have managed to get it printet, but it prints all the records in the table on every person that displays on the website (http://gyazo.com/13f271bbb8c4e83ff9ecd9908545c854 where it says "Betalt" it should just be ONE correct for each one).
The code for that part is here:
if ($row[9] == $row[1]) {
$betalt = "Ja";
}
$row[9] is the value from table SI_PAYMENTS. And $row[1] is the value from table BUSS1.
These two values should be the same if the record exists in SI_PAYMENTS, and if it exists, I want the webpage to display "Yes". But if it don't find it, I want the webpage to display "No".
EDIT
Here's my SQL Query:
SELECT buss1.navn, buss1.plassnummer, buss1.telefon, buss1.epost, buss1.fodselsdato, buss1.pastigningssted, buss1.bilettype, buss1.ankommet, buss1.merknader, si_payment.ac_inv_id FROM buss1, si_payment ORDER BY buss1.plassnummer ASC
I think you need to JOIN the two tables. At the moment, you will get every row from table buss1 next to every row from si_payment. So if there are 6 rows in buss1 and 4 in si_payment, you'll end up with 24 rows. I suspect there is a column in the two tables that links them, so you need a JOIN: something like this
SELECT buss1.navn, buss1.plassnummer, buss1.telefon, buss1.epost, buss1.fodselsdato, buss1.pastigningssted, buss1.bilettype, buss1.ankommet, buss1.merknader, si_payment.ac_inv_id
FROM buss1 INNER JOIN si_payment WHERE buss1.some_column = si_payment.another_column
ORDER BY buss1.plassnummer ASC
I can't tell what some_column and another_column should be, I'm afraid. But if you change those, that will give you only the matching rows from the two tables. If that's not quite right, you may need a LEFT JOIN, which will give you all rows from the first table and the matching rows from the same table.
If I've misunderstood, I apologise.
I need to be able to pinpoint a value in a MySQL table which is defined by two variables.
On the frontend of the site, there is a form which accepts a variety of fields. For this example let’s focus on these two:
Account Number
Account Name
I have developed a script which will use an ajax script to check the “Account Number” once entered and if it finds a match will display the “Account Name” when the user tabs out of the field.
The difficulty is to find a single result from the format of the database tables. For example:
”SELECT * FROM example_table WHERE name=’$accountnumber’”
Provides a list of all the values that equal the account number, but does not provide any record of the account name.
”SELECT * FROM example_table WHERE name=’$accountname’”
Provides a list of all the values that equal the account names, but does not provide any record of the account number.
The $record value is the only common thread between $accountnumber and $accountname.
So all in all, I need assistance creating the loop which can first take the $accountnumber value to find the $record value associated with that number. Secondly it will take the determined $record value and match it to the $accountname value. There is only one $accountnumber and $accountname value per unique $record value.
UPDATED: There have been several good comments on this question. To help provide more background, there is only one table. The best discriminator available seems to be the title value. Here is a link to the table snippet to view in greater detail:
https://docs.google.com/file/d/0By2lFlhEzILjbE1uT1hkVURmczA/edit?usp=sharing
So ultimately in this sample, a user would type 246802 and the result that is filtered out would be Fred’s Account.
Sounds like these are in the same table? Is there any discriminator to tell you whether name holds an accountnumber or accountname?
In any even, with the following assumptions you could try an ugly self join:
There are only two records with the record ID you want
these are multiple columns in the same table holding different information in the ambiguous column names
there is no better way to discriminate the record type
If so, something like this self-join should get you started:
SELECT t2.name as accountnumber from example_table as t1
INNER JOIN example_table as t2 on t1.recordID=t2.recordID
WHERE t1.name='$accountname'
EDIT Note - if my assumptions are correct and if this is data you are inheriting, I feel for you and you should look to improve it's structure. If you are designing it like this, you may want to think about it some more first.
EDIT 2
You probably want to put an index on the name column (this is the discriminator I would used based on your example).
Your query can be something like this:
SELECT t1.value as accountnumber,t2.value as accountName from example_table as t1
INNER JOIN example_table as t2 on t1.record=t2.record
WHERE t1.name='accountNumber' and t2.name='accountName'
See this SQL Fiddle: http://www.sqlfiddle.com/#!2/97c2f/1
I have a table in MySQL that I'm accessing from PHP. For example, let's have a table named THINGS:
things.ID - int primary key
things.name - varchar
things.owner_ID - int for joining with another table
My select statement to get what I need might look like:
SELECT * FROM things WHERE owner_ID = 99;
Pretty straightforward. Now, I'd like users to be able to specify a completely arbitrary order for the items returned from this query. The list will be displayed, they can then click an "up" or "down" button next to a row and have it moved up or down the list, or possibly a drag-and-drop operation to move it to anywhere else. I'd like this order to be saved in the database (same or other table). The custom order would be unique for the set of rows for each owner_ID.
I've searched for ways to provide this ordering without luck. I've thought of a few ways to implement this, but help me fill in the final option:
Add an INT column and set it's value to whatever I need to get rows
returned in my order. This presents the problem of scanning
row-by-row to find the insertion point, and possibly needing to
update the preceding/following rows sort column.
Having a "next" and "previous" column, implementing a linked list.
Once I find my place, I'll just have to update max 2 rows to insert
the row. But this requires scanning for the location from row #1.
Some SQL/relational DB trick I'm unaware of...
I'm looking for an answer to #3 because it may be out there, who knows. Plus, I'd like to offload as much as I can on the database.
From what I've read you need a new table containing the ordering of each user, say it's called *user_orderings*.
This table should contain the user ID, the position of the thing and the ID of the thing. The (user_id, thing_id) should be the PK. This way you need to update this table every time but you can get the things for a user in the order he/she wants using ORDER BY on the user_orderings table and joining it with the things table. It should work.
The simplest expression of an ordered list is: 3,1,2,4. We can store this as a string in the parent table; so if our table is photos with the foreign key profile_id, we'd place our photo order in profiles.photo_order. We can then consider this field in our order by clause by utilizing the find_in_set() function. This requires either two queries or a join. I use two queries but the join is more interesting, so here it is:
select photos.photo_id, photos.caption
from photos
join profiles on profiles.profile_id = photos.profile_id
where photos.profile_id = 1
order by find_in_set(photos.photo_id, profiles.photo_order);
Note that you would probably not want to use find_in_set() in a where clause due to performance implications, but in an order by clause, there are few enough results to make this fast.
I have a page that retrieves records from 1 table in a database when a certain condition is met.
What I want to achieve is to provide the use to with an opportunity to update each record displayed using text boxes.
I am having trouble interpreting what logic to proceed with after the user hits the 'submit' button.
Normally, if I'm updating one record (or a static number of records), I will use the apporpriate amount of SQL statements.
Since the amount of records are dynamically generated, what is the best way to update all at once? How would I know which records were retrieved in the first place to update?
FOR EXAMPLE:
OK, We have a table with student ids (ID), names (SNAME), subjects (SUBJ), grade for each subject (GRADE) and general remarks (COMMENTS).
I want to retrieve information about all students that got an 'A', and write UNIQUE congratulatory remarks for each student (such as 'good job', or 'congratulations', or etc.)
I'd retrieve the records and lay them out on the page, with a text box next to each student record for the comments to be entered. Because I don't know how many text boxes to make, I give the text boxes dynamically generated names using the student ID. The user now enters unique comments for each student, and clicks on submit.
Now, how am I supposed to update these records with the values entered in each text box?
I wouldn't know which students were retrieved in the first place - how would I know what names to use? I'm trying to avoid having to execute the query again after submitting - but is there any other way?
Hope this question was not too confusing.
thanks
Further expanding earlier answers:
You need a loop (e.g. foreach) to display and save the textareas. If the names of the textareas include the students ID, you don't need to know the name, because the text is inserted to the database by the primary key (the students ID). You may name your form-elements as array, to iterate over them, for example (where the numbers are the IDs):
<textarea name="comment[2345234]"></textarea>
<textarea name="comment[8957485]"></textarea>
Read it out as described by #evan:
foreach((array)$_POST['comment'] as $studentId => $studentComment)
{
var_dump($studentId, $studentComment);
}
And if you implement this whole thing as self-requesting form (Affenformular in german), you may also use just one single loop to save and output the textareas.
"I don't think you're understanding what I'm trying to ask." Maybe you don't understand the answers, even you stated it. You don't need a students name to save a database record. But if you really want to submit it, you may also use hidden inputs.
Use foreach() to find the values you care about, put them in an array, and process the array.
Expanding on #Ignacio's answer to make it more easily understandable:
foreach($_POST as $name_of_input => $value_of_input)
{
// do stuff - here is something so you can see the results after the submit
echo "$name_of_input :: $value_of_input <br>";
}