MySQL join same table twice on different columns without a clash - php

This is the query:
SELECT * FROM property_table AS property
INNER JOIN property_classification AS classifications
ON property.classification_id = classifications.id
INNER JOIN property_classification AS classonrequest
ON property.classonrequest_id = classonrequest.id
WHERE property.id=5000 LIMIT 1;
Notice that I'm using the same table property_classification on two fields property.classification_id and property.classonrequest_id.
The structure of property_classification is something like:
id | a1 | a2 | a3 | ... | d1 | d2
When I execute the query above in MySQL Query Browser, I get something like this:
id | other 'property' fields | id | a1 | a2 | a3 | ... | id | a1 | a2 | a3 | ...
But in my PHP script I am returning associated arrays, and all duplicate field names are overwritten.
What I want is the query to return the two joined tables under the name of their table i.e.:
classifications.id | classifications.a1 | classifications.a2 | classifications.a3
and
classonrequest.id | classonrequest.a1 | classonrequest.a2 | classonrequest.a3
How do I do that?

You need to use table aliases and rename the columns:
SELECT classifications.id as cid,
classifications.a1 as c_a1,
. . .
classificaitions.d2 as c_d2
classonrequest.a1 as cr_a1,
. . .
FROM property_table AS property
INNER JOIN property_classification AS classifications
ON property.classification_id = classifications.id
INNER JOIN property_classification AS classonrequest
ON property.classonrequest_id = classonrequest.id
WHERE property.id=5000
LIMIT 1;
To make your job easier, you can run a query like:
select concat('c_', column_name, ', ')
from information_schema.columns
where table_name = 'classification';
This will list all the column names for the first group (and you can repeat for the second group using a different prefix.

SELECT property.*, classifications.*, classonrequest.* FROM property_table AS property
INNER JOIN property_classification AS classifications
ON property.classification_id = classifications.id
INNER JOIN property_classification AS classonrequest
ON property.classonrequest_id = classonrequest.id
WHERE property.id=5000 LIMIT 1;
But you still won't get the specific table names.

Related

How to get 3 Users on one ROW using SQL ? (MySQL)

I have two arrays like this,
First Table (infos):
------------------------------
| ID | User1 | User2 | User3 |
------------------------------
| 1 | 20 | 30 | 12 |
------------------------------
Second Table (Users):
---------------------
| ID | Name | Email |
---------------------
| 12 | Test | Test# |
---------------------
| 20 | Bla | Test# |
---------------------
| 30 | Bate | Test# |
---------------------
I want to get the information of users on one row from the IDs on the first table.
I try by getting The row from the first table and fetching on users, but I want to optimize the function with just one Query.
SELECT * FROM infos;
SELECT * FROM Infos i,Users u WHERE u.ID = u.User1 (or 2 ...)
Is there any solution ?
You could use joining the table users 3 times, one for each userid you want show the related name (or other values):
select a.id
, a.user1
, b.Name as user1name
, a.user2
, c.name as user2name
, a.user3
, d.name as user3name
from infos a
inner join Users b on a.user1 = b.id
inner join Users c on a.user1 = c.id
inner join Users d on a.user1 = d.id
And just as suggested, you should not use old implicit join syntax based on comma-separated table names and where clause, you should use (since 1992) explicit joins. This syntax performs the same query, but is more clear.
This is a design error. Use a N:N relation (an additional table) to allow any number of users for the first table. With the relation, other queries will be easier.
A relation table looks like this:
create table relation
(
table1_id int unsigned not NULL,
table2_id int unsigned not NULL,
primary key(table1_id,table2_id)
);
A typical query (and I dislike a.* generally):
select a.*, b.*
from table1 a, table2 b, relation r
where r.table1_id = a.id
&& r.table2_id = b.id

MYSQL slow query when getting total rows from another table using while loop

I am new to mysql and I am attempting to get all ID from another table where ID is equal to ID from table 1 and another conditions.
Table 1
+---------------+
| ID model line |
+---------------+
| 1 XX C1 |
| 2 AA C3 |
| 3 SS C1 |
+---------------+
Table 2 ( So if my query is ID = 1 AND model = XX GROUP BY line the total rows from table 2 will return 3 since ID 1,4 and 5 is true.
+----------------------------+
| ID InspectionID model line |
+----------------------------+
| 1 1 XX C1 |
| 2 1 AA C3 |
| 3 1 SS C1 |
| 4 1 XX C2 |
| 5 1 XX C4 |
+----------------------------+
So far i have this query inside a PHP while loop it return what i wanted but the query is really slow.
$query = "SELECT * FROM table2 WHERE inspectionID = '$ID' AND model = '$modelID' GROUP BY line
So i think the best way is to join table1 and table2 and add a column total
sadly my knowledge on mysql and joining table is limited, any suggestions is appreciated.
my target is to create below.
+---------------------+
| ID model line total |
+---------------------+
| 1 XX C1 3 |
| 2 AA C3 0 |
| 3 SS C1 0 |
+---------------------+
Pretty simple join and aggregation. working demo
(note demo includes both answers so far and results.)
We left join so we keep all records from table 1 and join to table 2 to get records matching from table 1. We set the limit on model on the join itself so the filtering is applied to the table2 before the join occurs. thus the count will only include model XX and all other counts for models will be zero.
SELECT T1.ID, T1.Model, T1.Line, count(T2.ID)
FROM table1 T1
LEFT JOIN Table2 T2
on T1.Model = T2.Model
and T2.Model = 'XX'
GROUP BY T1.ID, T1.Model, T1.Line
ORDER BY T1.ID
Just create an SQL View:
CREATE VIEW TABLE_1_2_VIEW AS
SELECT A.id, A.model, A.line, B.inspectionID, COUNT(B.ID) Total
FROM table_1 A LEFT JOIN table_2 B
ON A.model=B.model
GROUP BY A.id, A.model, A.line, B.inspectionID
ORDER BY A.id, A.model, A.line;
You can query the data from this view as if it were a table.
SELECT id, model, line, IF(model='XX', Total, 0) Total
FROM TABLE_1_2_VIEW
WHERE inspectionID=1;
Just that the data in this view would not be updatable.

sql where clause for each row of a subquery

I have 2 tables in MSSql
table_a:
data|id_1|timeInIntForm
------------------------------
data1 | 1/22323/3 | 1433721600
data2 | 1/22323/3 | 1433721660
and I have another table
table_b
data|(string list of ids)|startTimeinIntform|EndTimeInIntForm
--------------------------------------------------------------
dataA| (a_1223233_z a_1223233_x) | 1433721601 | 1433721659
datab| (a_1223233_z a_1223233_x) | 1433721602 | 1433721645
I want to do a
select * from table_a where id_1 = 'someId'
and timeInIntForm between 'time1' and 'time2'
and not between TableB_row1[startTimeinIntform] and TableB_row1[EndTimeInIntForm]'
.
.
.
and not between TableB_rowN[startTimeinIntform] and TableB_rowN[EndTimeInIntForm]'
The ids do not match but can be correlated on a different table that has
table_c:
data|id_1|id_2
-----------------------------
data| 1/22323/3 | a_1223233_z
data| 1/22323/4 | a_1223233_x
my initial thought is in PHP to get the rows from table_b and then as I select from table_a build the not between clause from each row in table_b. But I would LOVE to do this in one select statement if possible. Any ideas?
I edited it to have some "sample" data I was asked for. I am stumped on how to join these .. I admit freely I am not a pro or even poor at joins but I am really stumped on how to join table b to a and c
Well I am not sure exactly without the tables but I think this would do it.
Select a.*
From table_a a
join table_c c
on a.ID_1 = c.ID_1
join table_b b
on c.ID_2 = b.ID_2
Where a.ID_1 = 'someid'
and a.timeinintform not between 'time1' and 'time2'
and a.timeinintform not between b.starttimeininform and b.endtimeinintform

Matching and returning rows in php and MySQL

I would love to get some help with this. I'm using php and MySQL to build a website. I currently have 3 tables, I'll include less in the examples. Basically I have a users table, a groups table and a grouplink table. What I have is the uid from the users table.
How should I go about it in php so I could, let's say: match users-uid to grouplink-uid, get the grouplink-gid it matches with, match grouplink-gid to groups-gid and return groups-grpname? And goes on a while loop so all group names the user is associated with are displayed.
Thanks in advance to those who will be willing to extend a hand.
users
-------
| uid |
-------
| 1 |
-------
groups
---------------
| gid |grpname|
---------------
| 1 | grp1 |
---------------
| 2 | grp2 |
---------------
grouplink
-------------------
| glid| uid | gid |
-------------------
| 1 | 1 | 1 |
-------------------
| 2 | 1 | 2 |
-------------------
uid is fk to uid in users while gid is fk to gid in groups
That's just a simple 2-way join query:
SELECT users.uid, groups.gid, groups.grpname
FROM users
INNER JOIN grouplink ON users.uid = grouplink.uid
INNER JOIN groups ON grouplink.gid = groups.gid
the actual retrieval of a joined query result is no different than a single table query - you've just got more fields to deal with.
The SQL query that will get you what you're looking for goes something like this (assuming no null values in the grouplink table):
SELECT u.uid, g.gid, g.grpname
FROM users u
JOIN grouplink gl ON u.uid = gl.uid
JOIN groups g ON gl.gid = g.gid
Here is one way:
SELECT users.uid, groups.gid, groups.grpname
FROM users u, groups g, grouplink gl
WHERE g.id = gl.gid
AND gl.uid = u.uid
When the user-id is in the variable $iUserId you could query following sql string:
$sSql = "SELECT groups.`grpname` FROM groups
INNER JOIN grouplink ON groups.`gid` = grouplink.`gid`
WHERE grouplink.`uid` = '" . intval($iUserId) . "'";
$rRes = mysql_query($sSql);
$aGroups = array();
while (($aRow = mysql_fetch_array($rRes)) !== false) {
$aGroups[] = $aRow['grpname'];
}
Now all groups associated with the user are in the array $aGroups.

Querying 6 tables unable to echo info from master table

I am trying to query 6 separate tables in my mysql database, the structures are as follows;
item
itemitemid | item | description | brand | date | time | path |
actor
actoractorid | name | actorthumb | bio |
brand
brandbrandid | brandname | description | image |
movie
moviemovieid | title | genre | year | moviethumb | synopsis|
users
userid | name | surname | email | password |
request
requestid | userid | itemid | brandid | movieid | actorid | content | requestdate |
Using the following query I can display for example where the requestid=1 I can see the movie in the request, the actor in the movie, the item of clothing they were wearing and its brand.
$requestid = mysql_real_escape_string($_GET['requestid']);
$query = "select r.requestid, m.*, a.*, i.*, b.*
FROM request r INNER JOIN movie m ON m.movieid = r.movieid
INNER JOIN actor a ON a.actorid = r.actorid
INNER JOIN item i ON i.itemid = r.itemid
INNER JOIN brand b ON b.brandid = r.brandid
WHERE r.requestid = $requestid";
However when I try to echo out "content" and "request date" from the request table. The data simply doesn't appear. I also cannot get the info from the user table, e.g the user logging the request by by adding the following join;
$query = "select r.requestid, m., a., i., b., u.*
INNER JOIN users u ON u.userid = r.userid
Please advise?
You aren't SELECTing those fields. Right now, you're only SELECTing r.requestid from the requests table. You need to add references to every field you want to echo.
As far as the User join, you just seem to be joining on the wrong field. You need to join on u.userid = r.userid. Right now, you're joining on u.itemid which doesn't exist. You'll also need to change your SELECT statement to report the fields you want (e.g. SELECT ... , u.name, u.email).
As an aside, you should avoid SELECTing table.* where possible. This can break things when you add a field to a table but don't account for that when processing the results of a query. You should try to be explicit as possible, and SELECT only the fields you want to use - e.g. SELECT users.name, users.email rather than doing SELECT users.*.

Categories