SQL query same table twice but get one output column only mysql - 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.

Related

Select join two tables and loop to get two different values

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

MySql query to fetch data in 3rd table from 1st table

I have three tables.
Fee table which contains Fee_id and Fee_name...
Session table which contains session_id and fee_id(foreign key).
classfee_charge table which contains session_id(foreign key),class_id(fo[![enter image description here][1]][1]reign key) and amount.
I have to store amount of fee classwise in classfee_charge table.
How to fetch fee_name in classfee_charge table?
You can put the current session_id (1 in the code bellow) after you group by Fee_name to have the aggregate data for each kind of expense :
SELECT
Fee.Fee_id,
Fee.Fee_name
FROM
Fee, Session
WHERE
Fee.Fee_id = Session.Fee_id
AND
Session.session_id = 1
GROUP BY
Fee.Fee_name
The result :
Fee_id Fee_name
1 Expense
SQL Fiddle for more details
SELECT f.Fee_name from fee f
INNER join session s
on s.Fee_id=f.Fee_id
INNER join classfee_charge cf
on cf.session_id=s.session_id

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...
)
;

Organizing data output with MySQL

I have the following table with data:
t1 (results): card_id group_id project_id user_id
The tables that contain actual labels are:
t2 (groups): id project_id label
t3 (cards): id project_id label
There could be multiple entries by different users.
I need help with writing a query to display the results in a table format with totals counts corresponding card/group. Here's my start but I'm not sure that I'm on the right track...
SELECT COUNT(card_id) AS cTotal, COUNT(group_id) AS gTotal
WHERE project_id = $projID
Unless I'm mistaken, it seems that all you need to do is group by card_id and group_id for the given project_id and pull out the count for each group
SELECT card_id, group_id, COUNT(user_id) FROM mytable
WHERE project_id = 001
GROUP BY (card_id, group_id);
EDIT:
Taking into account the card and group tables involves some joins, but the query is fundamentally the same. Still grouping by card and group, and constraining by project id
SELECT c.label, g.label, COUNT(t1.user_id) FROM mytable t1
JOIN groups g ON t1.group_id=g.id
JOIN cards c ON t1.card_is=c.id
WHERE t1.project_id = 001
GROUP BY (c.card_id, g.group_id)
ORDER BY (c.card_id, g.group_id);
I don't think you can get a table as you want with just SQL. You'll have to render the table in code by iterating over the results. How you do that depends on what language/platform you are using.
if you know for a fixed fact that there are nine groups, then just include those groups in subqueries - similar to this:
select cTotal, g1.gTotal as Group1, g2.gTotal as Group2... etc
from
( SELECT COUNT(card_id) AS cTotal
, COUNT(group_id) AS gTotal
WHERE project_id = $projID
AND group_id = 1 ) g1
, ( SELECT COUNT(card_id) AS cTotal
, COUNT(group_id) AS gTotal
WHERE project_id = $projID
AND group_id = 2 ) g2
etc.