Select join two tables and loop to get two different values - mysql

I need to query the RELATIONS table (WHERE between two dates) and get the ENTITY_ID related of each SOURCE/ACCOUNT pairs in the RELATIONS table.
- ENTITIES table
ENTITY_ID (PK)
ENTITY_NAME
- ACCOUNTS table
SOURCE (PK)
ACCOUNT (PK)
ENTITY_ID (FK)
- RELATIONS table
RELATION_ID (PK)
SOURCE_1 (FK)
ACCOUNT_1 (FK)
SOURCE_2 (FK)
ACCOUNT_2 (FK)
TIMESTAMP
Is there a way to do this in one query?
Output of query should look like this:
RELATION_ID
SOURCE_1
ACCOUNT_1
ENTITY_ID_1 (ENTITY_ID (from ACCOUNTS table) related to SOURCE_1 and ACCOUNT_1)
SOURCE_2
ACCOUNT_2
ENTITY_ID_2 (ENTITY_ID (from ACCOUNTS table) related to SOURCE_2 and ACCOUNT_2)
I have an idea on how to get ENTITY_ID_1, but not sure how to get ENTITY_ID_2 at the same time.
SELECT
R.RELATION_ID
,R.SOURCE_1
,R.ACCOUNT_1
,A.ENTITY_ID AS ENTITY_ID_1
,R.SOURCE_2
,R.ACCOUNT_2
FROM RELATIONS R
JOIN ACCOUNTS A
ON R.SOURCE_1 = A.SOURCE
AND R.ACCOUNT_1 = A.ACCOUNT
WHERE R.TIMESTAMP >= DATETIME1 AND R.TIMESTAMP < DATETIME2
Any thoughts on a better title for this question is welcomed.

I think you just need two JOINs:
SELECT R.RELATION_ID, R.SOURCE_1, R.ACCOUNT_1,
A1.ENTITY_ID AS ENTITY_ID_1,
A2.ENTITY_ID AS ENTITY_ID_2,
R.SOURCE_2, R.ACCOUNT_2
FROM RELATIONS R JOIN
ACCOUNTS A1
ON R.SOURCE_1 = A1.SOURCE AND
R.ACCOUNT_1 = A1.ACCOUNT JOIN
ACCOUNT A2
ON R.SOURCE_2 = A2.SOURCE AND
R.ACCOUNT_2 = A2.ACCOUNT
WHERE R.TIMESTAMP >= DATETIME1 AND
R.TIMESTAMP < DATETIME2

Related

List rows that have an ID in common in the same table with MySQL

I'm building an activities website and I want to show on user's profiles the common activities I'm going to with this other user.
So I have a table as follow :
Every time a user clicks "join" on an activity page, a new row is added to this table with :
the user_id who joined
the activity_id (event) attended
So on each user's profile, I want to list the different activities we have in common.
If the user's IDs are for example 1 and 10, then I can list the activities they go to with this query :
SELECT * FROM `activity_user` WHERE user_id IN(1, 10)
However, how to update this query to return only activities IDs they have in common?
It's a simple JOIN with the same table:
SELECT a1.activity_id
FROM activity_user a1
JOIN activity_user a2 ON a2.activity_id = a1.activity_id
WHERE a1.user_id = 1
AND a2.user_id = 10
Another way is to GROUP BY activity_id and only return activities, which both users have, by counting the rows per group:
SELECT activity_id
FROM activity_user
WHERE user_id IN(1, 10)
GROUP BY activity_id
HAVING COUNT(*) = 2
If the number of user is only limited to 2, this is quite simple using intersect clause -
SELECT activity_id
FROM `activity_user`
WHERE user_id = 1
INTERSECT
SELECT activity_id
FROM `activity_user`
WHERE user_id = 10
For two users you can join two SELECT against same table on activity_id
SELECT a.activity_id
FROM test a
JOIN (SELECT activity_idFROM test WHERE user_id = 10) b ON a.activity_id = b.activity_id
WHERE a.user_id = 1

SQL query same table twice but get one output column only mysql

I need to list the two ENTITY_ID's (by querying the RELATIONS table with WHERE between two dates) related to each SOURCE/ACCOUNT pairs in the RELATIONS table.
- ENTITIES table
ENTITY_ID (PK)
ENTITY_NAME
- ACCOUNTS table
SOURCE (PK)
ACCOUNT (PK)
ENTITY_ID (FK)
- RELATIONS table
RELATION_ID (PK)
SOURCE_1 (FK)
ACCOUNT_1 (FK)
SOURCE_2 (FK)
ACCOUNT_2 (FK)
TIMESTAMP
The query below retrieves the ENTITY_ID of one SOURCE/ACCOUNT pair (SOURCE_1/ACCOUNT_1), but I'd also need the ENTITY_ID of SOURCE_2/ACCOUNT_2, not as second column in the output, but as a second row (value).
SELECT A.ENTITY_ID
FROM RELATIONS R
JOIN ACCOUNTS A
ON R.SOURCE_1 = A.SOURCE
AND R.ACCOUNT_1 = A.ACCOUNT
WHERE R.TIMESTAMP >= DATETIME1 AND R.TIMESTAMP < DATETIME2
Example of output needed (1 column, 2 values):
ENTITY_ID
Output record #1 1234
Output record #2 1235
If you need the values in different rows, then you can do:
SELECT A.ENTITY_ID
FROM RELATIONS R JOIN
ACCOUNTS A
ON (R.SOURCE_1 = A.SOURCE AND
R.ACCOUNT_1 = A.ACCOUNT
) OR
(R.SOURCE_2 = A.SOURCE AND
R.ACCOUNT_2 = A.ACCOUNT
)
WHERE R.TIMESTAMP >= DATETIME1 AND
R.TIMESTAMP < DATETIME2;
ORs generally kill the performance of JOINs, but this will work if your data is not very big.

mysql query based on result from one

This will probably be easy for allot of you guru's.
I am trying to get * from two tables.
First table i can match with a user_id. structure is as follows:
table name: order_new
id | service_id | user_id | total_price | total_price_tax | orderstatus | notes | orderdate
table name 2: order_new_items
id | id_order | name | qty | price
The first table ( order_new ) i can get by using the session id. that first table has a row called "id". That id has items in table 2 ( order_new_items ) under the row of "id_order".
Im not sure on how to join the two and pull all data from both tables matching id from first table and id_order from second table
SELECT * FROM order_new, order_new_items where order_new.id = order_new_items.id and order_new.id = 4711
This will retrieve all rows where an ID exists in bot tables. It will not retrieve rows from table order_new when there are no corresponding rows in order_new_items (i.e. empty order)
To achieve this, you need to use:
SELECT * FROM order_new
LEFT JOIN order_new_items on order_new.id = order_new_items.id
where order_new.id = 4711
probably you need to list columns explicitly instead of *
MySQL-Only:
SELECT * FROM order_new o, order_new_items i WHERE user_id = '7' AND o.id_order = i.id;
I'm assuming, that id from order_new is the primary key for the table, while id_order is the foreign key for the 1:n relationship.
To be noted, the 7 is an example of course and needs to be substituted with whatever value you're looking for.
According to comments, I'm answering another question:
$result = mysql_query("SELECT * FROM order_new WHERE user_id = 7");
while ($row = mysql_fetch_array($result)) {
//store order information
$res2 = mysql_query("SELECT * FROM order_new_items WHERE id_order = $row[id]");
while($row2 = mysql_fetch_array($res2)) {
//store further information
}
}
Try this, this will fetch you data from both tables based on conditon.
SELECT a*, b.id, b.name, b.qty, b.price FROM order_new a
INNER JOIN order_new_items b on b.id_order = a.id
WHERE a.id = 100

Join table on pattern match

I have been struggling with this for several hours, so any feedback or advise is very welcome.
I have three tables:
users
id name email
1 test test#test.com
2 test2 test2#test.com
pets
pet_id pet_name user_id
1 sam 2
2 sally 1
transactions
trans_id custom
1 1
2 pid2
3 pid1
OK, what I would like to do is get transaction data relating to the user. So in the 'transactions' table 'custom' value 1 would relate to 'users' with the id. Thats the simple bit...
'Transactions' with 'pid' relate to the pets id, so 'pid2' relates to sally, whose user is user id 1. So I need to join the transaction table when custom relates to the user id or if its prefixed with 'pid' and the appending value relates to the 'pet_id'.
Here's an example of the result I would like:
Transactions relating to user_id 1:
trans_id 1, custom 1
trans_id 2 custom pid2 (this is because the pets owner is user_id 1)
Here is where I am with my attempt at the moment:
SELECT users.*, transactions.*
FROM users
LEFT JOIN transactions on users.id = transactions.custom
This is where I'm falling over:
SELECT users.*, transactions.*
FROM users
LEFT JOIN pets ON pets.user_id = user.id
LEFT JOIN transactions on (users.id = transactions.custom
OR pets.pet_id REGEXP '^pid(transactions.custom)')
If you can't change the table design and the prefix pid is fixed you could use
OR (
pets.pet_id = SUBSTR(transactions.custom, 3)
AND SUBSTR(transactions.custom, 1 FOR 3) = 'pid')
see documentation to SUBSTR and because MySQL automatically converts numbers to strings as necessary, and vice versa, see: http://dev.mysql.com/doc/refman/5.7/en/type-conversion.html
You HAVE to refactor Your DB. Current structure will guarantee of speed problems.
Table transactions should looks like
CREATE TABLE transactions
(
id Int NOT NULL, (id of transaction)
pet_id Int, (can be null)
user_id Int (can be null)
other columns here...
)
;

SELECT value from table because two conditions are not met

I have three tables on my database:
ts_room
Fields:
id (PK)
capacity
img
notes
building_id
roomstructure_id
lecturestyle_id
ts_request
Fields
id (PK)
day_id
period_id
roompref_id (FK > ts_roompref.id)
ts_roompref
id (PK)
request_id (FK > ts_request.id)
room_id (FK > ts_room.id)
I would like to write a MySQL PDO query that selects rows from ts_room provided that after running the rows on ts_roompref (checking ts_roompref.room_id against ts_room.id) and finding a match - we would then look up the value in ts_request and see whether day_id and period_id both match 1. It would return the total count.
I hope the above explanation makes sense.
Essentially - requests for rooms are made with this system and ts_roompref stores the room preferences made for each request. I am trying to find out whether a particular room is booked on a day and period (denoted by day_id and period_id in the ts_request table), in this case Monday (1) and period (1).
how about this?
SELECT COUNT(*) totalCOUnt
FROM ts_room a
INNER JOIN ts_roompref b
ON a.id = b.room_ID
INNER JOIN ts_request c
ON b.request_ID = c.roompref_ID
WHERE c.day_ID = 1 AND c.period_ID = 1
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins