mySQL - Compare if values are equal from 2 tables - mysql

I'm a newbie and i'm trying to check if the location in STUDENT table is equal to the location of the QR. Anyone knows how to do this?
Student TABLE
|Student_ID|Name|Gender|Location|
---------------------------------
| 0118210 |Dex | Male | PJU1/42|
QR Table
|QR_Code|Date Generated|QR_Location|
------------------------------------
| 4747 | 4/6/2018 | PJU1/42 |
EDIT
Sorry for the lack of information given. Basically i would need to build a backend system using Laravel that would generate a QR CODE. Whenever i generate the QR Code, a unique "QR_CODE" would be generated and insert into the QR Table along side with the "Date Generated" and "QR_Location". So whenever i use my mobile phone to scan the QR Code i would like to check if my current location is equal to the location of the location of the QR_Location.
Hope that this would give u guys some idea of what i am trying to achieve.
Thank you

There are plenty of way to do this. But i would do this as
select s.*
from Student s
where exists (select 1 from QR q where s.Location = q.QR_Location);

Related

MySQL: Structuring Notification Message System So Parts of It Can Be Clicked

For my senior design project, I am working on a project which is an application where an engineer can upload his/her design either 3D, 2D, or 1D and get votes by their customers which design looks good. The issue I am having is structuring my notification to where parts of the notification can be clicked and viewed in detail. If I want to insert a value before, in between, or at the end of the notification message like handles, do I need like a config file with custom messages in the backend and then insert the handles from the frontend? See examples 1 and 2 below.
Example 1 of what the notification should look like:
"Design {design_name} voted by {customer_name} and {50} other customers"
Example 2 of what the notification should look like:
"Your design {design_name} and {10} other designs got votes"
As you can see in the examples above, parts of it can be clicked to see in detail. In example 1, I should be able to click on 50 and view the remaining customers who voted for that particular design. Same concept applies to example 2. Any advice will be greatly greatly appreciated. Thank you.
//Notifications MySQL Table Fields
+----------+----------+----------+----------+-----------+----------+
| id | from_id | to_id | type | design_id | viewed |
+----------+----------+----------+----------+-----------+----------+
//3D Design MySQL Table Fields
+----------+----------+-------------+-------------+------------+
|design_id | user_id | description | design_name | image |
+----------+----------+-------------+-------------+------------+
//2D Design MySQL Table Fields
+----------+----------+-------------+-------------+------------+
|design_id | user_id | description | design_name | image |
+----------+----------+-------------+-------------+------------+
//1D Design MySQL Table Fields
+----------+----------+-------------+-------------+------------+
|design_id | user_id | description | design_name | image |
+----------+----------+-------------+-------------+------------+
With the design of the tables as they are, you could get the parameters by the following.
#notification_1
SELECT
design_name,
count(*) - 1 as number_of_other_voters,
voters_table.voters_name
FROM design_table
LEFT JOIN votes_table ON voted_design_id = design_id
LEFT JOIN voters_table on votes_table.voter_id = voters_table.id
WHERE design_id = 'x'
GROUP BY design_id
If you wanted to jam everything into a query, then you can do the following (although I highly suggest against it):
#notification_1
SELECT CONCAT("Design ", design_name, " voted by ", voters_table.voters_name, " and ", count(*) - 1 as number_of_other_voters, " other customers")
FROM design_table
LEFT JOIN votes_table ON voted_design_id = design_id
LEFT JOIN voters_table on votes_table.voter_id = voters_table.id
WHERE design_id = 'x'
GROUP BY design_id
Though this will get you a string, and possibly a meaningful one, this will not achieve the usability goals that you have laid out. If you are using PHP to build a web interface, for example, you would just run the first query and assign the results to a variable, then build your string with the links filled in with some IDs.
foreach($result as $row){
$notification = "Design " . $row['design_name'] .
" voted by <a href='/user/" . $row['customer_id'] . "'>" . $row['customer_name'] .
"</a> and <a href='/some_voting_page_url/" . $row['vote_id'] . "'>. " $row['number_of_other_voters'] " . other customers"
}
Any language (JS, PHP, Java, C, etc) will have the ability to load data from a query into a pre-fabricated string with the above method. The second notification would just be a count on the votes table (which you have not shown where the votes are being stored in your example)
SELECT count(*) FROM (SELECT DISTINCT design_id FROM votes_table WHERE user_id = 'x');
That's the best I can do with the tables as they are currently designed (considering you add a user table and a votes table). As pointed out by #Gilbert Le Blank in the comment on the main task, you should only have one table with the ability to mark what the dimension of the design is rather than three design tables unless the data stored in each is fundamentally different.

How to extract relational data from a flat table using SQL?

I have a single flat table containing a list of people which records their participation in different groups and their activities over time. The table contains following columns:
- name (first/last)
- e-mail
- secondary e-mail
- group
- event date
+ some other data in a series of columns, relevant to a specific event (meeting, workshop).
I want to extract distinct people from that into a separate table, so that further down the road it could be used for their profiles giving them a list of what they attended and relevant info. In other words, I would like to have a list of people (profiles) and then link that to a list of groups they are in and then a list of events per group they participated in.
Obviously, same people appear a number of times:
| Full name | email | secondary email | group | date |
| John Smith | jsmith#someplace.com | | AcOP | 2010-02-12 |
| John Smith | jsmith#gmail.com | jsmith#somplace.com | AcOP | 2010-03-14 |
| John Smith | jsmith#gmail.com | | CbDP | 2010-03-18 |
| John Smith | jsmith#someplace.com | | BDz | 2010-04-02 |
Of course, I would like to roll it into one record for John Smith with both e-mails in the resulting People table. I can't rule out that there might be more records for same person with other e-mails than those two - I can live with that. To make it more complex ideally I would like to derive a list of groups, creating a Groups table (possibly with further details on the groups) and then a list of meetings/activities for each group. By linking that I would then have clean relational model.
Now, the question: is there a way to perform such a transformation of data in SQL? Or do I need to write a procedure (program) that would traverse the database and do it?
The database is in MySQL, though I can also use MS Access (it was given to me in that format).
There is no tool that does this automatically. You will have to write a couple queries (unless you want to write a DTS package or something proprietary). Here's a typical approach:
Write two select statements for the two tables you wish to create-- one for users and one for groups. You may need to use DISTINCT or GROUP BY to ensure you only get one row when the source table contains duplicates.
Run the two select statements and inspect them for problems. For example, it's possible some users show up with two different email addresses, or some users have the same name and were combined incorrectly. These will need to be cleaned up in order to proceed. There is great way to do this-- it's more or less a manual process requiring expert knowledge of the data.
Write CREATE TABLE scripts based on the two SELECT statements so that you can store the results somewhere.
Use INSERT FROM or SELECT INTO to populate the tables from your two SELECT statements.

Save MySQL data in order

I am having problem with storing the data in mysql. I want to save the data in an unordered way inside a database. for eg.
Number | Name | Section | Grades |
1 | x | A | 80% |
3 | z | B | 72% |
2 | y | C | 55% |
I want to save the data inside the database in such a way that the data is saved according to the number in order. It should be stored in order of number.
I saw the function GROUP BY which show the data in an arranged way. But I need to save the data in database file that way. Is there any way by which I can make the data in order inside database file.?
Thanks for your time.
this one is will going to display in grades format like as,3,2,1 :
SELECT number,name, section, grades FROM tablename ORDER BY grades DESC;
The order in which the data is save is not relevant to you as you can use the ORDER BY operator to order your select results.
An example query by sorting the data will be:
SELECT * FROM <table> ORDER BY name ASC;
You can see the full documentation on:
https://dev.mysql.com/doc/refman/5.0/en/sorting-rows.html
Reading the comments, a view may be usefull for you, so you can access the data in an ordered way from the other software:
CREATE VIEW <view_name> AS SELECT * FROM <table> ORDER BY name ASC;
And the you can access the view with
SELECT * from <view_name>
and your data will be in the order you defined in the view query.
You can find the full view reference on:
https://dev.mysql.com/doc/refman/5.0/en/create-view.html

Database design and query optimization/general efficiency when joining 6 tables in mySQL

I have 6 tables. These are simplified for this example.
user_items
ID | user_id | item_name | version
-------------------------------------
1 | 123 | test | 1
data
ID | name | version | info
----------------------------
1 | test | 1 | info
data_emails
ID | name | version | email_id
------------------------
1 | test | 1 | 1
2 | test | 1 | 2
emails
ID | email
-------------------
1 | email#address.com
2 | second#email.com
data_ips
ID | name | version | ip_id
----------------------------
1 | test | 1 | 1
2 | test | 1 | 2
ips
ID | ip
--------
1 | 1.2.3.4
2 | 2.3.4.5
What I am looking to achieve is the following.
The user (123) has the item with name 'test'. This is the basic information we need for a given entry.
There is data in our 'data' table and the current version is 1 as such the version in our user_items table is also 1. The two tables are linked together by the name and version. The setup is like this as a user could have an item for which we dont have data, likewise there could be an item for which we have data but no user owns..
For each item there are also 0 or more emails and ips associated. These can be the same for many items so rather than duplicate the actual email varchar over and over we have the data_emails and data_ips tables which link to the emails and ips table respectively based on the email_id/ip_id and the respective ID columns.
The emails and ips are associated with the data version again through the item name and version number.
My first query is is this a good/well optimized database setup?
My next query and my main question is joining this complex data structure.
What i had was:
PHP
- get all the user items
- loop through them and get the most recent data entry (if any)
- if there is one get the respective emails
- get the respective ips
Does that count as 3 queries or essentially infinite depending on the number of user items?
I was made to believe that the above was inefficient and as such I wanted to condense my setup into using one query to get the same data.
I have achieved that with the following code
SELECT user_items.name,GROUP_CONCAT( emails.email SEPARATOR ',' ) as emails, x.ip
FROM user_items
JOIN data AS data ON (data.name = user_items.name AND data.version = user_items.version)
LEFT JOIN data_emails AS data_emails ON (data_emails.name = user_items.name AND data_emails.version = user_items.version)
LEFT JOIN emails AS emails ON (data_emails.email_id = emails.ID)
LEFT JOIN
(SELECT name,version,GROUP_CONCAT( the_ips.ip SEPARATOR ',' ) as ip FROM data_ips
LEFT JOIN ips as the_ips ON data_ips.ip_id = the_ips.ID )
x ON (x.name = data.name AND x.version = user_items.version)
I have done loads of reading to get to this point and worked tirelessly to get here.
This works as I require - this question seeks to clarify what are the benefits of using this instead?
I have had to use a subquery (I believe?) to get the ips as previously it was multiplying results (I believe based on the complex joins). How this subquery works I suppose is my main confusion.
Summary of questions.
-Is my database setup well setup for my usage? Any improvements would be appreciated. And any useful resources to help me expand my knowledge would be great.
-How does the subquery in my sql actually work - what is the query doing?
-Am i correct to keep using left joins - I want to return the user item, and null values if applicable to the right.
-Am I essentially replacing a potentially infinite number of queries with 2? Does this make a REAL difference? Can the above be improved?
-Given that when i update a version of an item in my data table i know have to update the version in the user_items table, I now have a few more update queries to do. Is the tradeoff off of this setup in practice worthwhile?
Thanks to anyone who contributes to helping me get a better grasp of this !!
Given your data layout, and your objective, the query is correct. If you've only got a small amount of data it shouldn't be a performance problem - that will change quickly as the amount of data grows. However when you ave a large amount of data there are very few circumstances where you should ever see all your data in one go, implying that the results will be filtered in some way. Exactly how they are filtered has a huge impact on the structure of the query.
How does the subquery in my sql actually work
Currently it doesn't work properly - there is no GROUP BY
Is the tradeoff off of this setup in practice worthwhile?
No - it implies that your schema is too normalized.

using MS Access 2007,

I am doing a project in MS Access 2007 where I am going to count the number of absences of each student. This will be the table:
name of student | absent1 | absent2 | absent3 | absent4 | absent5 | total
ryan llorcanuada| 05-7-12 | 05-8-12 | 05-9-12 |________ | _______ | 3
The maximum number of absences of each student is 5. So based from the table, the student got only 3 absences and the remaining fields are blank. Supposedly, the table will display 3 in the total field. How am I going to do that? What if the student has no absences?
So, is the question "What is the best way to design a table to store absences?" or is it "Given the following table, how can you calculate the number of absences a student has?"
I ask because the table as shown is a very bad way to structure your database. To solve the problem with this structure, you are probably going to have to use a series of IIF functions. Please try something and post what you've tried, then people can help you fix your answer.