Compare three tables for one answers in MySQL [closed] - php

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have been working with MySQL for a while now, and just recently found the need to manage my data better (MOAR DATA!)...
The problem I am having is this:
Table1: users
- id
Table2: companies
- companyid
- companyname
Table3: customers
- customerid
- companyid
I am trying to query the following.
I have the users ID, I need to use that to get the companyid from customers using the customerid, and return companyname based of the assigned companyid in customers.
It is very possible I am going about this very wrong. I understand that eventually the data is going to get very hard to read by eye as the data starts to grow. My concern is having the ability to associate and disassociate customers from businesses.
If you have any tips, or have a better strategy, or think I should just add this information into the users tables please let me know.

First off, you need some understandings on what Normalization is: http://support.microsoft.com/kb/283878
The database tables are not meant to be "read by eye". I'm pretty sure you are dealing with a very small database now, but imagine in the future you're dealing with thousands of tables with millions of rows, "visual inspection" is not going to work anymore.
A simple join would have given what you need:
SELECT t2.companyname
FROM table1 t1, table2 t2, table3 t3
WHERE t1.id = t3.customerid
AND t3.companyid = t2.company id
AND t3.customerid = (some id) //Depends on what your purpose is,
//this line can also be replaced by
//AND t1.id = (some id)
In your case, it is possible to combine User table and Customer table into one ONLY if all users are customers too. But it is definitely a NO to have company information in either User or Customer tables.

Assuming customers.customerid and users.id will be the same value, this should suffice:
SELECT companies.companyname
FROM customers
LEFT JOIN companies ON customers.companyid = companies.companyid
WHERE customers.customerid = 5
Here is a fiddle
Schema is on the left, sql is on the right.
Tables:
users
+--------+
| ID |
+--------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
| 11 |
| 12 |
| 13 |
+--------+
companies
+------------------------------------------+
| COMPANYID COMPANYNAME |
+------------------------------------------+
| 5 CompAlumpany |
| 9 Dergy Hergins LLC |
| 3 Smergy Berg Inc. |
| 23 Hergin Derz |
| 7 Comperation corpany |
| 11 Contagion Engine |
| 31 AEther Vial |
| 66 Necropotence |
| 90 Lord of Atlantis |
| 65 Snoogins |
| 51 Nickty-Schnickty-Schnoine |
| 58 Take a knee |
| 59 Coorprate |
+------------------------------------------+
customers
+--------------------------+
| CUSTOMERID COMPANYID |
+--------------------------+
| 1 5 |
| 2 9 |
| 3 3 |
| 4 23 |
| 5 7 |
| 6 11 |
| 7 31 |
| 8 66 |
| 9 90 |
| 10 65 |
| 11 51 |
| 12 58 |
| 13 59 |
+--------------------------+
Query Returns:
+---------------------+
| COMPANYNAME |
+---------------------+
| Comperation corpany |
+---------------------+

Posted on behalf of the OP.
I got the results I was looking for with the following:
SELECT t2.companyname FROM companies t2,customers t3 WHERE t3.companyid = t2.companyid AND t3.customerid=?
I was unaware I could create references, this will become very useful for me. Thank you!

Related

Select from multiple tables on reference table with same column name MYSQL/PHP

I need some help with MySQL/PHP. Which is the faster execution in code point of view.
I have below tables
1. table_content
--------------------------------
id | section | content_id
--------------------------------
1 | A | 15
2 | B | 25
3 | A | 9
--------------------------------
2. table_a
--------------------------------
id | name | message
--------------------------------
9 | John | Hello Everyone
15 | Smita | Hi
17 | Vinayak | How are you?
--------------------------------
3. table_b
--------------------------------
id | label | description
--------------------------------
1 | David | D1
5 | Alia | D2
25 | Vinay | D3
--------------------------------
I have above table structure. For me table_content is main table. I want below output through MySQL/PHP [As array and section as key].
Output
------------------------------------------------
id | section | name | message
------------------------------------------------
1 | A | Smita | Hi
2 | B | Vinay | D3
3 | A | John | Hello Everyone
------------------------------------------------
I have tried with SWITCH case. But not getting exact output.
Which is the better performance and fast execution? with MySQL or PHP. I have thousands of data like this.
Please help me to solve this problem.
Should be acheved via a JOIN.
Also ensure you have configured appropriater indexing, otherwise it will perform badly when you get to a large volume of data.
As i posted in my comment you need to Join the both tables, which must be UNION
SELECT tc.`id`, tc. `section` ,t1.`message`
FROM table_content tc JOIN (SELECT `id`, `name`, `message` FROM table_a UNION SELECT `id`, `label`, `description` FROM table_b) t1
ON tc.`content_id` = t1.`id`
id | section | message
-: | :------ | :-------------
1 | A | Hi
2 | B | D3
3 | A | Hello Everyone
db<>fiddle here

MYSQL UPDATE from SELECT INNER JOIN statement

Hello :) I am fairly new to using INNER JOIN and still trying to comprehend it's logic which I think I am sort of beginning to understand. After being across a few different articles on the topic I have generated a query for finding duplicates in my table of phone numbers.
My table structure is as such:
+---------+-------+
| PhoneID | Phone |
+---------+-------+
Very simple. I created this query:
SELECT A.PhoneID, B.PhoneID FROM T_Phone A
INNER JOIN T_Phone B
ON A.Phone = B.Phone AND A.PhoneID < B.PhoneID
Which returns the ID of a phone that matches another one. I don't know how to word that properly so here is an example output:
+---------+---------+
| PhoneID | PhoneID |
+---------+---------+
| 17919 | 17969 |
| 17919 | 22206 |
| 17919 | 23837 |
| 17920 | 17970 |
| 17920 | 22203 |
| 17920 | 23834 |
| 17921 | 17971 |
| 17921 | 22225 |
| 17921 | 22465 |
| 17921 | 24011 |
| 17921 | 24047 |
| 17922 | 17972 |
| 17922 | 22198 |
| 17922 | 23879 |
| 17923 | 17973 |
| 17923 | 22199 |
| 17923 | 23880 |
+---------+---------+
You can note that on the left there is repeating IDs, the phone number that matches will be on the right (These are just the IDs of said numbers). what I am trying to accomplish, is to actually change a join table relative to the ID on the right. The join table structure is as such:
+----------+-----------+
| T_JoinID | T_PhoneID |
+----------+-----------+
Where T_JoinID is a larger object with a collection of those T_PhoneIDs, hence the join table. What I want to do is take a row from the original match query, and find the right side PhoneID in the join table, then update that item in the Join to be equal to the left side PhoneID. Repeating this for each row.
It's sort of a way to save space and get rid of matching numbers, I can just point the matching ones to the original and use that as a reference when I need to retrieve it.
After that I need to actually delete the original numbers that I reset the reference for but... This seems like a job for 2 or 3 different queries.
EDIT:
Sorry I know I didn't include enough detail. Here is some additional info:
My exact table structure is not the same as here but I am only using the columns that I listed so I didn't consider the fact that any of the others would matter. Most of the tables have a unique ID that is auto incremented. The phone table has carrier, type, ect columns. The additional columns I felt were irrelevant to include, but if there is a solution that includes the auto incremented ID of each table, let me know :) Anyway, I sort of found a solution, using multiple queries though I am still interested to learn and apply knowledge based on this question. So I have a that join table that I mentioned. It might look something like this for the expected results. There is a before and after table in one sorry for poor formatting.
+--------------------+---------+----------+---------+
| Join Table Results | | | |
+--------------------+---------+----------+---------+
| Before | | After | |
| Join | Table | Join | Table |
| PersonID | PhoneID | PersonID | PhoneID |
| 1 | 1 | 1 | 1 |
| 1 | 2 | 1 | 2 |
| 1 | 3 | 1 | 3 |
| 2 | 4 | 2 | 1 |
| 2 | 5 | 2 | 5 |
| 2 | 6 | 2 | 6 |
| 3 | 7 | 3 | 5 |
| 3 | 8 | 3 | 5 |
| 3 | 9 | 3 | 5 |
| 3 | 10 | 3 | 8 |
| 3 | 11 | 3 | 9 |
+--------------------+---------+----------+---------+
So you can see that in the before columns, 7, 8, and 9 would all be duplicate phone numbers in the PhoneID - PhoneID relationship table I posted originally. After the query I wanted to retrieve the duplicates using the PhoneID - PhoneID comparison and take the ones that match, to change the join table in a way that I have shown directly above. So 7, 8, 9 all turn to 5. Because 5 is the original number, and 7, 8, 9 coincidentally were duplicates of 5. So I am basically pointing all of them to 5, and then deleting what would have been 7, 8, 9 in my Phone table since they all have a new relationship to 5. Is this making sense? xD It sounds outrageous typing it out.
End Edit
How can I improve my query to accomplish this task? Is it possible using an UPDATE statement? I was also considering just looping through this output and updating each row individually but I had a hope to just use a single query to save time and code. Typing it out makes me feel a tad obnoxious but I had hope there was a solution out there!
Thank you to anyone in advance for taking your time to help me out :) I really appreciate it. If it sounds outlandish, let me know I will just use multiple queries.

Trying to join tables in MySQL

i'm new to MySQL and PHP. And i have some problems trying to get data values from two tables in one query using JOIN. What i want to do is query "user_builds" and SUM(amount) where the owner_id=1 AND type=1. The problems comes in now where i have to grab the build_type from another table called "builds".
I have tried to solve this as i mentioned with JOIN, but the closest i came was to get the amount of rows that was equal to how many rows user_id=1 had.
What i want is select the total SUM of "amount"(user_builds) where "type=1"(builds) and "owner_id=1"(user_builds).
I hope you understand what i try to do here, if not i will try to elaborate it more. And also sorry for not providing any of the querys i tried, but as none of them worked it feels irrelevant. Thank you for your time.
Edit:
+-------------------+
| user_builds |
+---------+---------+----------+-------+
| id |owner_id | build_id | amount|
+---------+---------+----------+-------+
| 1 | 1 | 1 | 5 |
| 2 | 2 | 2 | 15 |
| 3 | 2 | 3 | 15 |
| 4 | 1 | 4 | 5 |
| 5 | 1 | 5 | 5 |
| 6 | 1 | 6 | 10 |
+---------+---------+----------+-------+
+----------------------+
| build |
+---------+------------+-----------+--------+
| id | name |description| type |
+---------+------------+-----------+--------+
| 1 | House | desc | 1 |
| 2 | Kitchen | desc | 2 |
+---------+------------+-----------+--------+
I want to query "user_builds" and get the total of "amount" where owner_id=1 and type=1. (type is found in "build" table).
Try this code, I hope it works appropriately.
select sum(ub.amount)
from user_builds ub
left join build b
on ub.build_id = b.id
where b.type=1
and ub.owner_id = 1
select SUM(amount) from user_builds left join builds on build.type = user_builds.type where "owner_id=1"
try this query and replace my query field with your original fields
best of luck...

Doctrine2: SUM on left join query

I'm trying to build a query with Doctrine, but i'm not sure if it can be done.
What i need is to get a result displaying the ID of a Requested Item and its SUM of Quantity already fulfilled.
I have four tables:
Request
RequestItems
Order
OrderItems
I can create a Request and assign one or more Items to this Request which are stored at RequestItems, then i need to create an Order to this Request, the Order must aim to fulfill the Requested Items, but it might be with a single Order or Multiple ones, therefore each Order contains one or many items which are stored at OrderItems.
The following is an example of tables:
Request
| ID | Date |
|----|------------|
| 1 | 2014-05-12 |
| 2 | 2014-05-13 |
RequestItems
| ID | RequestID | Name |Qtty |
|----|-----------|---------------------|-----|
| 1 | 1 | 60W Light Bulb | 5 |
| 2 | 1 | Bticino switch | 3 |
| 3 | 2 | 60W Light Bulb | 10 |
| 4 | 2 | 80W Light Bulb Warm | 15 |
Order
| ID | RequestId | Date | State |
|----|-----------|------------|-------|
| 1 | 1 | 2014-05-14 | 1 |
| 2 | 1 | 2014-05-15 | 1 |
| 3 | 2 | 2014-05-15 | 1 |
| 4 | 2 | 2014-05-16 | 1 |
| 5 | 2 | 2014-05-17 | 1 |
OrderItems
| ID | RequestItemsID | OrderID | Qtty |
|----|----------------|---------|------|
| 1 | 1 | 1 | 5 |
| 2 | 2 | 2 | 3 |
| 3 | 3 | 3 | 2 |
| 4 | 3 | 4 | 2 |
| 5 | 3 | 5 | 1 |
| 6 | 4 | 5 | 10 |
Here i have two Requests:
No. 1: Have two items requested (5 60W light bulbs, 3 Bticino switches)
No. 2: Have one item requested (10 60W light bulbs, 15 80W warm light bulbs)
For these requests i have created 5 Orders, two of them to fulfill first request and 3 to fulfill second request.
The first two Orders have addressed the first request and provided the requested items so first request should be completed.
The last three Orders are addressing the second Request and have provided already 5 of the 10 60W light bulbs and 10 of the 80W warm light bulbs.
What i need here is to get the ID and Quantity of the RequestItems and The SUM of Qtty on OrderItems grouped by the RequestItem ID and filtered by the Order State and Request ID
As a sample i need to get how many RequestedItems where requested and have already been ordered for the Request No. 2 where its Order State is 1
| RequestItemsID | QttyRequested | QttyOrdered (SUM) |
|----------------|---------------|-------------------|
| 3 | 10 | 5 |
| 4 | 15 | 10 |
This result groups requested items by its ID and return the Requested Quantity, also SUM the already ordered ammounts of OrderItems for this RequestItem
Given this result i can calculate pending items also.
I've managed to solve this issue building two Queries one to get RequestedItems and one to get OrderedItems and matching these two with PHP but i think it is possible to do this on the database side.
If anyone can help me with this it would be much appreciated.
Thanks.
UPDATE #1:
I have issues with subqueries inside a join when using the QueryBuilder, but i managed to build a working query, adding the subquery in the join condition.
I'm adding my working query below but i still need to do multiple checks to see if it is really my answer.
You can get the example result by executing
SELECT ri.ID AS RequestItemsID, ri.Qtty AS QttyRequested,
SUM(oi.qtty) AS QttyOrdered
FROM RequestItems ri
INNER JOIN Order AS o ON o.RequestId = ri.RequestId
INNER JOIN OrderItems AS oi ON oi.OrderId = o.ID
WHERE ri.RequestId = 2 AND o.State = 1
GROUP BY ri.RequestId, o.State
It seems Doctrine doesnt support subqueries in the JOIN part of the query but i managed to add a subquery in the condition part of my JOIN.
Based on https://groups.google.com/forum/#!topic/doctrine-user/0rNbXlD0E_8 this can be solved with IN(SUBQUERY)
This is what is working right now given the example in the OP
SELECT ri.ID AS RequestItemsID, ri.Qtty AS QttyRequested, COALESCE(SUM(oi.Qtty), 0) AS QttyOrdered
FROM RequestItems AS ri
LEFT JOIN OrderItems AS oi ON oi.RequestItemsID = ri.ID AND oi.OrderID IN (
SELECT o.ID FROM Order AS o WHERE o.State = 1 AND o.RequestID = 2
)
WHERE ri.RequestID = 2
GROUP BY ri.ID;

How do I sort data from a mysql db according to a unique and predetermined order, NOT asc or desc

I need to show 1000 test questions to a student, 10 per page.
The questions are in a mysql table, the answers will go in another table.
I need each students questions to appear in a different predetermined order than any other students. The sort order is predetermined when they register and placed in a usermeta table.
In the usermeta table there is a column that lists the order in which the questions should be shown. The order in that column is unique to each student and looks like this example: 8|14|97|54|21|37|54|61 ...etc.
The first question to be shown to the student would be question #8, and then question #14, and then question #97, and so on, listing 10 per page.
I don't need to sort the questions asc or desc. Also, I can change the db structure if that would help find a solution.
Also, I can change the db structure if that would help find a
solution.
If changing the db structure is possible, then instead of storing the sorting order as a pipe separated string, store it in a separate table that maps each question to the order it should appear in for a given student. i.e.
student_id, sort_order, question_id
1 1 8
1 2 2
1 3 97
Then join on your sorting table when selecting your questions for a particular student.
SELECT q.* FROM
questions q
JOIN questions_sorting_order qso
ON q.id = qso.question_id
ORDER BY qso.sort_order
WHERE qso.student_id = :student_id
SELECT * FROM ints;
+---+
| i |
+---+
| 0 |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
+---+
SELECT i2.i*10+i1.i x
, FIND_IN_SET(i2.i*10+i1.i,'8,14,97,54,21,37,54,61') y
FROM ints i1
, ints i2
HAVING y > 0
ORDER
BY y;
+----+---+
| x | y |
+----+---+
| 8 | 1 |
| 14 | 2 |
| 97 | 3 |
| 54 | 4 |
| 21 | 5 |
| 37 | 6 |
| 61 | 8 |
+----+---+
Note that 54 is ignored second time around

Categories