joining two mysql tables without unique common field - php

I made a big mistake in inserting data from my survey application and now I really stuck! I have list of movies in my table "featuredfilms_EN" with these fields: movieName, ImdbId(unique Id of movies), year. In my survey app, I asked users about their favorite movies and I stored their answers in the "Answer_CROWD" table which has these fields: qId, answer.
Now I faced a big problem that is: I need to join these two tables, but since I forgot to store the unique_Id(ImdbId) in "Answer_CROWD" table, I cannot!:(
I appreciate if someone can help me if there is a way that I can join these two tables? I am really stuck... I have a deadline tomorrow and I just found this big issue now.

it looks like you could concat the movieName & year & match on that
SELECT * FROM featuredfilms_EN
JOIN Answer_CROWD ON lower(answer)=lower(concat(trim(movieName), '_', year))

I write here because in comment will be confused,
now i can't see fields of tables so i write generic but i'think you understand:
update query:
1 add a field called for example Film_id to Answer_CROWD
2 select id,concat(trim(movieName), '_', year) as title from Featuredfilms_EN and put in $rows
3 in a
`foreach ($rows as $value ){
$id=$value['id'];
$title=$value['title'];
$sql="UPDATE Answer_CROWD SET Film_id='$id' WHERE lower(answer)=lower('$title')";
....do query
}`

Related

Query selected columns from two tables with a Condition clause

I have two tables-
1) ****Company_Form****
[Contract_No#,Software_Name,Company_Name,Vendor_Code]
2) ****User_Form****
[Contract_No,Invoice_No#,Invoice_Date,Invoice_Amount,Invoice_Submit_Date]
Fields denoted with # and bold are primary keys.
=>The user has to enter a software name for which he wants to get the data of.
=>I have to structure a query in which I have to display the result in the following form:
[Contract#,Software_Name,Company_Name,Invoice_No,Invoice_Date,Invoice_Submission_Date]
Now,
one Contract_No can contain many Invoice_no under its name in
the User Form table.
One Contract_No can occur one time only in
Company_Form table
The retrieved records have to be group by the latest Invoice_Date
I came to the logic that:
I have to first retrieve all the contract numbers with that software
name from Company_Form table.
I have to query that contract number from User_Form table and display
the data for each matched contract no. fetched from Company_Form
table.
The problem is that I am unable to structure a query in SQL that can do the task for me.
Kindly help me in formulating the query.
[PS] I am using SQL with PHP.
I tried a query like:
I tried one approach as :
SELECT a.ContractNo,a.SoftwareName,a.CompanyName,b.InvoiceNo,b.InvoiceDate,b.InvAmount,b.InvoiceSubmitDate
FROM Company_Form as a,User_Form as b
WHERE b.ContractNo IN(SELECT ContractNo FROM Company_Form WHERE
SoftwareName='$Sname') AND a.ContractNo=b.ContractNo;
But I am getting a error that sub query returns more than 1 row.
Can I get help from this?
I am assuming you are attempting to find the most recent price of the user selected software and its corresponding invoice. Here is an approach to do this. If this is tested to your satisfaction, I can add necessary explanation.
select uf.Contract_No#,
cf.Software_Name,
cf.Company_Name,
uf.Invoice_No#,
uf.Invoice_Date,
uf.Invoice_Amount,
uf.Invoice_Submit_Date
from User_Form uf
inner join (
-- Most recent sale of software
select Contract_No#, max(Invoice_Date)
from User_Form
group by Contract_No#
) latest
on (
-- Filter via join for latest match records
uf.Contract_No# = latest.Contract_No#
and uf.Invoice_Date = latest.Invoice_Date
)
inner join Company_Form cf
on cf.Contract_No# = uf.Contract_No#
where cf.Software_name = :software_name
If the requirement allows your sub query to return more than one row, I would suggest you to use IN instead of = in the where clause of your main query.
Please note that I have just looked at the query and have not fully understood the requirements.
Thanks.
I worked around for some time and finally came to the following query which works like a charm
SELECT a.ContractNo,a.SoftwareName,a.CompanyName,b.InvoiceNo,b.InvoiceDate,b.InvAmount,b.ISD
FROM Company_Form as a,User_Form as b
WHERE b.ContractNo IN (SELECT ContractNo FROM Company_Form WHERE SoftwareName='$Sname')
AND a.ContractNo=b.ContractNo;
If anybody needs help in understanding the logic of this query,feel free to comment below.

Showing users only their information

Okay so im new to databases, and have created a site with a users table, and i also hace a list table, where suers can insert list items, however when they log in everyones list is appearing, how can i link the user table to the lists table, is it creating the same field in each one and using a foreign key? Sorry I am very new to this. Appreciate any help
I think you can just use user_id on both tables to fix this. Let me give an example:
Table A (user_id, username, password)
Table B (list_item_id, user_id , any_other_attribute)
When you design your tables like this a simple sql call will do what you need like:
SELECT 'list_item_id','any_other_attribute' FROM Table B Where user_id=$user_id
Where $user_id is the user_id of the one's who loginned your system.
Also by your question, i suggest you to read about these : 'sessions' , 'sql queries' , 'generating sql query results' on your choice of programming language.
It calls MANY MANY relationnship. There mus be 1 table with fields user_id and field_id that will join this 2 tables

Order by votes - PHP

I have a voting script which pulls out the number of votes per user.
Everything is working, except I need to now display the number of votes per user in order of number of votes. Please see my database structure:
Entries:
UserID, FirstName, LastName, EmailAddress, TelephoneNumber, Image, Status
Voting:
item, vote, nvotes
The item field contains vt_img and then the UserID, so for example: vt_img4 and both vote & nvotes display the number of votes.
Any ideas how I can relate those together and display the users in order of the most voted at the top?
Thanks
You really need to change the structure of the voting table so that you can do a normal join. I would strongly suggest adding either a pure userID column, or at the very least not making it a concat of two other columns. Based on an ID you could then easily do something like this:
select
a.userID,
a.firstName,
b.votes
from
entries a
join voting b
on a.userID=b.userID
order by
b.votes desc
The other option is to consider (if it is a one to one relationship) simply merging the data into one table which would make it even easier again.
At the moment, this really is an XY problem, you are looking for a way to join two tables that aren't meant to be joined. While there are (horrible, ghastly, terrible) ways of doing it, I think the best solution is to do a little extra work and alter your database (we can certainly help with that so you don't lose any data) and then you will be able to both do what you want right now (easily) and all those other things you will want to do in the future (that you don't know about right now) will be oh so much easier.
Edit: It seems like this is a great opportunity to use a Trigger to insert the new row for you. A MySQL trigger is an action that the database will make when a certain predefined action takes place. In this case, you want to insert a new row into a table when you insert a row into your main table. The beauty is that you can use a reference to the data in the original table to do it:
CREATE TRIGGER Entries_Trigger AFTER insert ON Entries
FOR EACH ROW BEGIN
insert into Voting values(new.UserID,0,0);
END;
This will work in the following manner - When a row is inserted into your Entries table, the database will insert the row (creating the auto_increment ID and the like) then instantly call this trigger, which will then use that newly created UserID to insert into the second table (along with some zeroes for votes and nvotes).
Your database is badly designed. It should be:
Voting:
item, user_id, vote, nvotes
Placing the item id and the user id into the same column as a concatenated string with a delimiter is just asking for trouble. This isn't scalable at all. Look up the basics on Normalization.
You could try this:
SELECT *
FROM Entries e
JOIN Voting v ON (CONCAT('vt_img', e.UserID) = v.item)
ORDER BY nvotes DESC
but please notice that this query might be quite slow due to the fact that the join field for Entries table is built at query time.
You should consider changing your database structure so that Voting contains a UserID field in order to do a direct join.
I'm figuring the Entries table is where votes are cast (you're database schema doesn't make much sense to me, seems like you could work it a little better). If the votes are actually on the Votes table and that's connected to a user, then you should have UserID field in that table too. Either way the example will help.
Lets say you add UserID to the Votes table and this is where a user's votes are stored than this would be your query
SELECT Users.id, Votes.*,
SUM(Votes.nvotes) AS user_votes
FROM Users, Votes
WHERE Users.id = Votes.UserID
GROUP BY Votes.UserID
ORDER BY user_votes
USE ORDER BY in your query --
SELECT column_name(s)
FROM table_name
ORDER BY column_name(s) ASC|DESC

SQL Query result, comparison and where clause

I am building a site and i need to retrieve some information. I have this query.
$SQL = "SELECT distretto_108, provinca_113, regioni_116, tipologia_pdv_106,
richiesta_ccnl_107, coop_va_109, nome_pdv_110,
indirizzo_pdv_111, localita_112
FROM civicrm_value_informazioni_su_tute_le_schede_p_22 ";
I need to add this other code:
WHERE civicrm_event.title_en_US='".addslashes($_GET["titles"])."'
but it's not working...
i need to compare let's say the id of another table with the id of the current table... How to do that?
Thanks in advance...
You should learn something about joining tables...
Do not know what the relation is between the two tables (simply said: what column from one table is pointing to what column at other one), but try something similar (modification needed to meet You DB structure) - now lets assume both tables have related column called event_id:
$SQL = "SELECT distretto_108, provinca_113, regioni_116, tipologia_pdv_106,
richiesta_ccnl_107, coop_va_109, nome_pdv_110,
indirizzo_pdv_111, localita_112
FROM civicrm_value_informazioni_su_tute_le_schede_p_22 cvistlsp22
LEFT JOIN civicrm_event ce ON ce.event_id = cvistlsp22.event_id
WHERE ce.title_en_US='".mysql_real_escape_string($_GET["titles"])."'";
civicrm_value_informazioni_su_tute_le_schede_p_22 table name is very long and You will not be able to create a table with such long name in other DBMS (e.g. ORACLE), so try to make it shorter while still self-describing...
If You want to join tables they have to have a relation, read more about relations and how to use them here: http://net.tutsplus.com/tutorials/databases/sql-for-beginners-part-3-database-relationships/
You are retrieving the data from table civicrm_value_informazioni_su_tute_le_schede_p_22 in your query while the where clause you are adding, refers to the table civicrm_event. You need to add this new table in the from clause and do a join among the two tables using some common key. Example below:
$SQL = "
SELECT distretto_108, provinca_113, regioni_116, tipologia_pdv_106, richiesta_ccnl_107, coop_va_109, nome_pdv_110, indirizzo_pdv_111, localita_112
FROM civicrm_value_informazioni_su_tute_le_schede_p_22
JOIN civicrm_event ON civicrm_value_informazioni_su_tute_le_schede_p_22.ID_PK = civicrm_event.ID_FK
WHERE civicrm_event.title_en_US='".addslashes($_GET["titles"])
";
You need to replace the ID_PK and ID_FK with the relevant Primary and Foreign Keys that bind the tables together.
Please note using query params like that is not recommended. Please read PHP Documentation here for more explanation.

How can I make this database schema better?

I currently have two tables in which stores the attendances of a student in a course. I have the hub_attendance table which stores the total attendances of a student and the hub_attendance_lesson where it stores the attendance of each lesson that a student has or has not attended. I'm not sure if this is correct or if I'm doing anything wrong, I'm a beginner in databases!
hub_attendance:
id
student_id
course_id
total_lessons
total_lessons_so_far
total_attended
total_absent
total_excused_absent
total_late
total_excused_late
hub_attendance_lesson:
id
lesson_id
course_id
student_id
date
attended
absent
excused_absent
late
excused_late
EDIT:
So I've gotten rid of the first table completely and this is my new single table.
Hub_Attendance:
id
lesson_id
course_id
student_id
date
attendance
As Dutchie432 said, you don't need the first table because it introduces unnecessary redundancy and you can count those statistics on the fly. Such aggregate tables can be a good solution if performance is an issue, but they should be used only as a last resort.
About the second table - you have separate fields attended, absent, excused_absent,
late and excused_late. Aren't these mutually exclusive? So only one of them can be true for one row? If so, you may be better off with one enumeration field called for example attendance, which would take different values for each of those states. In that way you could't have rows where none of the flags, or more than one flag, is set.
Here's what you need:
**Course**
id, name, etc...
**Lesson**
id, courseid, name, etc...
**Attendance**
id, studentid, lessonid, lateness, etc...
**Enrolment**
id, courseid, studentid, startdate, etc...
You need the enrolment table to know that students should be on a course even if they never turn up for lessons. The attendance table will allow you to have many students per lesson and many lessons per student. This is a many-to-many table. Any aggregation and counting can be done in SQL.
If I understand your schema correctly, Your first table can be totally eliminated. You should be able to fetch the totals using MySQL.
select count(id) as total_late from hub_attendance_lesson where late=true and student_id=TheUserId
Remove this first table, every total can be fetch using SQL :
SELECT count(id) AS absent
FROM hub_attendance_lesson
WHERE lesson_id = <your lesson id>
AND absent = <false / true>
I guess you'll be able to adapt this code for your needs.

Categories