SQL in PHPMYADMIN - mysql

I help with an SQL (using phpmyadmin) to join these tables and create a CLUB MEMBERSHIP list for a particular club, however I need to indicate whether the member is a club president, vice president,etc or just an ordinary member:
CLUBS: CLUBID,PRESIDENTID(memberID),VICEPRESIDENTID(memberID),TREASURER(memberID),
SECRETARY(MemberID)
MEMBERS_CLUB:
MEMBERID,CLUBID
MEMBERS:
MEMBERID, NAME,ADDRESS

There are probably half a dozen ways to solve this, and you certainly could come up with a way to make this table structure work for you, but it's probably not going to be pretty. Part of making this work well is determining what information you need to get out as well as store in the database. In this structure, it's very hard to get the member's officer status from their name, so we can improve that by changing your structure. On the other hand, if all you ever needed was a list of officers for each club, your current structure would be okay.
You could add a "member status" field to MEMBERS_CLUB (and remove the four corresponding columns from CLUBS). Each member gets a row for each club or position they hold.
SELECT `MEMBERS`.`NAME`, `MEMBERS_CLUB`.`STATUS`, `CLUBS`.`CLUBID`
FROM `MEMBERS`, `MEMBERS_CLUB`, `CLUBS`
WHERE `MEMBERS`.`MEMBERID` = `MEMBERS_CLUB`.`MEMBERID`
which is close but gives us duplicates if there are duplicates in the table, for instance if you have two entries for Bob, one listing him as president and one listing him as secretary. By using GROUP_CONCAT() we can accomplish exactly what you are looking for while dealing properly with duplicated names:
SELECT `MEMBERS`.`NAME`, GROUP_CONCAT(`MEMBERS_CLUB`.`STATUS`), `CLUBS`.`CLUBID`
FROM `MEMBERS`, `MEMBERS_CLUB`, `CLUBS`
WHERE `MEMBERS`.`MEMBERID` = `MEMBERS_CLUB`.`MEMBERID`
GROUP BY `NAME`

Related

Access Rental Database: Preventig an equipment to be used in two different projects

I'm looking for a way to make a database for equipment managment but I don't know how to go forward from my point.
I have now 3 core tables to do this part, the EQUIPMENT table, where I have a list of all the equipment I have (with the different units on record and everything),
besides this one I have the PROJECT table, where I have all the information of the rental service and I also have a PROJECT_DETAILS where I place the equipment for the given project
Examples:
EQUIPMENT TABLE: Brand,Model,Internal Number:
[Ford;Transit; 1][Ford;Transit;2][Ford;Transit;3][Mercedes;Sprinter;1][Mercedes;Sprinter;2] Etc...
PROJECT TABLE: Project code, Start, End, Client Name:
[XX001;2016/08/05;2016/08/10;Steve][XX002;2016/08/06;2016/08/8;Bill] etc...
PROJECT DETAILS: Project Code, Equipment, Internal Number:
[XX001;Transit;1][XX001;Transit;2][XX002;Transit;3][XX002;Sprinter;1]
So what I want to do is when trying to make a new project, I want the equipment to dissapear from its combo box if the equipment is in use in another project
I would continue to flesh out the database schema with the following additional tables:
RENTAL: This represents "the rental contract itself." The rental might be active, or it might be being contemplated. Perhaps, all RENTALs belong to (one) PROJECT ...
RENTAL-EQUIPMENT: This one-to-many table lists the items that are to be rented when this rental contract goes into effect.
RENTAL-EQUIPMENT-RESERVED-NOW: This is “where the rubber hits the road.” This table contains an entry for every piece of EQUIPMENT that is "right now, irrevocably, 'off the lot.'" It is related both to RENTAL-EQUIPMENT (to justify the presence of the record), and directly to EQUIPMENT ("where's that dump truck and why is it not here on the lot? Oh. We rented it. I see..."). I'd probably insert a record into the table when the equipment went out the door, and remove the record when the equipment was returned. The presence of a row in this table ... only one row per equipment_id is allowed ... is sufficient to indicate that a piece of equipment is reserved or off-the-lot, and why.
In this view of things, PROJECTs, from time to time, "rent things," or "plan to rent things in the future." (Nobody rents anything unless it is associated with a project, say...) Each RENTAL consists of a list of equipment to be rented. Then, when stuff goes off-the-lot and we need to be able to quickly(!) account for it (without poring through a bunch of RENTAL-EQUIPMENT and RENTAL records in a very-laborious query ...), the RESERVED-NOW table gives us an immediate answer.
You should also familiarize yourself with the concept of TRANSACTIONs, which Access fully supports. A "transaction" is an atomic group of SQL statements that will be "all or nothing." For instance, when you start to process the departure of a piece of equipment from the lot, you "start a transaction." Then, you perform the SQL statements needed to insert into RENTAL-EQUIPMENT-RESERVED-NOW and to update RENTAL-EQUIPMENT records and so-on ... then, you "COMMIT the transaction." All of the changes that you made, all at once, then "become permanent."
What? "Oopsie! Something went wrong!!" No problem: just ROLLBACK the transaction instead, and you're right back where you started. Nothing that you did during the transaction 'actually happened.' (Rollbacks often appear in on error goto... blocks.)
Finally, also look at things like "foreign keys" and "referential integrity."
I think something like this would work. Basically depending on on how your project is set up, you would want to look at anything where the end date is past your current client trying to schedule "schedule_date" let's say and before or equal to the schedule_date. This way if they select a date range, anything that is between those dates wouldn't show up.
SELECT * FROM equipment WHERE internal_number NOT IN (SELECT internal_number FROM project INNER JOIN project_details ON product_details.project_code = project.project_code WHERE end_date >= schedule_date and begin_date <= schedule_date)
From the way I read your question, it sounds like ProjectDetails is recording the combinations of the project and the equipment. It also sounds like you aren't interested in keeping a historical of those assignments, and are therefore removing them from projectdetails when they are no longer assigned.
So (again, if I understand correctly), what you want to do is to show all of the records in the equipment table that does not exist in the projectdetails table - correct?
SELECT * FROM equipment INNER JOIN projectdetails ON equipment.equipid = projectdetails.equipid
I broadly concur with DHW and Mike Robinson - From my reading of your structure you are using the project details table as a junction table to relate the equipment and the projects. Comparison of this table to the equipment should give a list of all unused equipment.
I had a go on an access database at my end and I joined the Equipment Table to the Project Details Table and did a left join so that ALL equipment was shown. I then added the Equipment field of the Project Details table. In order for this to work you need a relationship between the Project Details Table and the Equipment table and you must ensure the Project Details Equipment Field and the Equipment Table Internal Number are same data type ie Long Integer. I then ensured then put a filter on the Project Details.Equipment field criteria set to Null. The SQL I used for this was
SELECT EquipmentTable.InternalNumber, EquipmentTable.Brand,EquipmentTable.Model, ProjectDetails.Equipment FROM EquipmentTable LEFT JOIN ProjectDetails ON EquipmentTable.InternalNumber = ProjectDetails.Equipment WHERE (((ProjectDetails.Equipment) Is Null));

Designing a correct table structure

We are trying to save the Family History of a particular foreign job applicant. Below are the details we have to save.
Familiy Member: Father|Mother|1st Brother| 2nd Brother| 1st Sister| etc etc
Health Status: Alive|Deceased
Health Condition (Negative/Positive): Arthritis |Asthma |COPD |Diabetes etc etc
Health Condition (Comment): Arthritis |Asthma |COPD |Diabetes etc etc
Overall Comment
Below is its UI, so you can understand it better.
Now our problem creating a database table for storing these information. Below are the things to be considered.
If the job applicant like, he can provide the data of any number of family members.
There are hundreds of items to come under "General Data". So we can't create columns in table for every single items in that.
"Overall History Comment" is a comment about the entire family history, not related to a particular member.
The table design we made is below
Here are some sample input to the table.
FamilyHistory
a) 1,1,1st Brother,Alive, Asthma, Not serious
b) 2,1,1st Brother,Alive, Cancer, Lung Cancer
c) 3,2,2nd Sister,Alive, Asthma,serious
d) 4,2,2nd Sister,Alive, Diabetes,serious
OverallComment
a) 1,1,1,Overall Condition Normal
b) 2,3,2,NULL
However we feel this design is bad due to the below points.
Have a look at the a) and b) of Family History input. The 1st brother of the job applicant have 2 health conditions. To enter this, 2 rows are inserted and all the details about him are repeated except the different health conditions.
Can you please let me know how to make this design better?
My first thought is: Why do you record this data? What is it good for? I cannot imagine its use. However, the answer will help design.
Is it important whether the second sister or the father has arthritis? If not, then why distinguish the two? You could go without Family member types. (If you want so use a text field where you type in '2nd sis', 'mom', 'father', whatever.)
Are you going to have reports on that (e.g. 20% of our applicants told us they have family members with cancer)? Or will you always simply look up one applicant and see their family entries? If the latter, you could make this one text column where you simply type in all members and their health (or have your program write this).
Another point: Why is OverallComment a separate table? Do you need this for internationalization? Or for database-wide text search? If not, make this a column in the related table instead.
applicant ( applicant_id , name , comment )
If you need the relational model for queries and reports, then have one table for the family member:
family_member ( family_member_id , applicant_id , family_member_type, alive, comment )
And another table for the several desease entries per member:
family_member_desease ( family_member_id , desease_id , comment )
Maybe you should add dates. E.g.: When was the father reported to be alive?

help with making SQL query efficient in MySql

I have 30 tables, each representing a different neighborhood.
Each table holds real estate listing with a "Price", "Number Of Rooms", "Square Feet" etc columns.
The end user would be able to choose as many neighborhoods as he likes with the
option to screen out results such as "At least 5 Rooms", "Below 250k" etc and
sort the results by "Lowest Price", "Time Submitted", you get the point.
Now I'm a programmer not a DBMS guy. I've search the web but feel that trying to build the query one step at a time would be the wrong approach without some guidance on what to avoid.
I would love to hear and learn from the StackOverflow community on best approaches with this one. Please help me sort this up.
EDIT: i'm currently using MyISAM
You should not have 30 tables. Normalize your schema:
NEIGHBORHOOD
ID, Name
PROPERTY
ID, NeighborhoodID, Name, Price,
Rooms, SquareFeet
Then you can join these together:
SELECT n.Name AS Neighborhood, p.Name AS Property, Price, Rooms, SquareFeet
FROM Property AS p
INNER JOIN Neighborhood AS n ON h.NeighborhoodID = p.ID
WHERE p.NeighborhoodID = X
Then you may need indexes on the tables as the data grows.
You should start modifying your database model. Creating 30 tables for storing the same data (real state information) is not adequate. Try to put all the data in a single table adding a column that indicates the neighborhood. This neighborhood could point to another table with the name, description, ... of the neighborhood. Then you can query a single table to search across all neighborhoods and optionally filtrate the neighborhood the user want to search for.
The best way is to change your db model, get rid of 30 tables, and put everything in one table. With your current model, I don't see any other ways but create a huge union (you can put it into a view, and query this view).

Organizational chart represented in a table

I have an Access application, in which I have an employee table. The employees are part of several different levels in the organization. The orgranization has 1 GM, 5 department heads, and under each department head are several supervisors, and under those supervisors are the workers.
Depending on the position of the employee, they will only have access to records of those under them.
I wanted to represent the organization in a table with some sort of level system. The problem I saw with that was that there are many ppl on the same level (for example supervisors) but they shouldn't have access to the records of a supervisor in another department. How should I approach this problem?
One common way of keeping this kind of hierarchical data in a database uses only a single table, with fields something like this:
userId (primary key)
userName
supervisorId (self-referential "foreign key", refers to another userId in this same table)
positionCode (could be simple like 1=lakey, 2=supervisor; or a foreign key pointing to another table of positions and such)
...whatever else you need to store for each employee...
Then your app uses SQL queries to figure out permissions. To figure out the employees that supervisor 'X' (whose userId is '3', for example) is allowed to see, you query for all employees where supervisorId=3.
If you want higher-up bosses to be able to see everyone underneath them, the easiest way is just to do a recursive search. I.e. query for everyone that reports to this big boss, and for each of them query who reports to them, all the way down the tree.
Does that make sense? You let the database do the work of sorting through all the users, because computers are good at that kind of thing.
I put the positionCode in this example in case you wanted some people to have different permissions... for example, you might have a code '99' for HR employees which have the right to see the list of all employees.
Maybe I'll let some other people try to explain it better...
Here's an article from Microsoft's Access Cookbook that explains these queries rather well.
And here is a somewhat chunky explanation of the same.
Here's a completely different method (the "adjacency list model") that you might find useful, and his explanation is pretty good. He also points out some difficulties with both methods (when he talks about the tables being "denormalized").

Searching a database of names

I have a MYSQL database containing the names of a large collection of people. Each person in the database could could have one or all of the following name types: first, last, middle, maiden or nick. I want to provide a way for people to search this database to see if a person exists in the database.
Are there any off the shelf products that would be suited to searching a database of peoples names?
With a bit of ingenuity, MySQL will do just what you need... The following gives a few ideas how this could be accomplished.
Your table: (I call it tblPersons)
PersonID (primary key of sorts)
First
Last
Middle
Maiden
Nick
Other columns for extra info (address, whatever...)
By keeping the table as-is, and building an index on each of the name-related columns, the following query provides an inefficient but plausible way of finding all persons whose name matches somehow a particular name. (Jack in the example)
SELECT * from tblPersons
WHERE First = 'Jack' OR Last = 'Jack' OR Middle = 'Jack'
OR Maiden = 'Jack' OR Nick = 'Jack'
Note that the application is not bound to only searching for one name value to be sought in all the various name types. The User can also input a specific set of criteria for example to search for the First Name 'John' and Last Name 'Lennon' and the Profession 'Artist' (if such info is stored in the db) etc.
Also, note that even with this single table approach, one of the features of your application could be to let the user tell the search logic whether this is a "given" name (like Paul, Samantha or Fatima) or a "surname" (like Black, McQueen or Dupont). The main purpose of this is that there are names that can be either (for example Lewis or Hillary), and by being, optionally, a bit more specific in their query, the end users can get SQL to automatically weed-out many irrelevant records. We'll get back to this kind of feature, in the context of alternative, more efficient database layout.
Introducing a "Names" table.
Instead (or in addition...) of storing the various names in the tblPersons table, we can introduce an extra table. and relate it to tblPersons.
tblNames
PersonID (used to relate with tblPersons)
NameType (single letter code, say F, L, M, U, N for First, Last...)
Name
We'd then have ONE record in tblPersons for each individual, but as many records in tblNames as they have names (but when they don't have a particular name, few people for example have a Nickname, there is no need for a corresponding record in tblNames).
Then the query would become
SELECT [DISTINCT] * from tblPersons P
JOIN tblNames N ON N.PersonID = P.PersonID
WHERE N.Name = 'Jack'
Such a layout/structure would be more efficient. Furthermore this query would lend itself to offer the "given" vs. "surname" capability easily, just by adding to the WHERE clause
AND N.NameType IN ('F', 'M', 'N') -- for the "given" names
(or)
AND N.NameType IN ('L', 'U', 'N') -- for the "surname" types. Note that
-- we put Nick name in there, but could just as eaily remove it.
Another interest of this approach is that it would allow storing other kinds of names in there, for example the SOUNDEX form of every name could be added, under their own NameType(s), allowing to easily find names even if the spelling is approximate.
Finaly another improvement could be to introduce a separate lookup table containing the most common abbreviations of given names (Pete for Peter, Jack for John, Bill for William etc), and to use this for search purposes (The name columns used for providing the display values would remain as provided in the source data, but the extra lookup/normalization at the level of the search would increase recall).
You shouldn't need to buy a product to search a database, databases are built to handle queries.
Have you tried running your own queries on it? For example: (I'm imagining what the schema looks like)
SELECT * FROM names WHERE first_name='Matt' AND last_name='Way';
If you've tried running some queries, what problems did you encounter that makes you want to try a different solution?
What does the schema look like?
How many rows are there?
Have you tried indexing the data in any way?
Please provide some more information to help answer your question.