join twice on the same table rails? - mysql

I want to join on the same table twice to get username and username_to
#array = UsersWalletsBalancesFrozen.
joins("INNER JOIN userds userdsidto ON transactions.user_id_to=userdsidto.id").
joins("INNER JOIN userds userdsid ON transactions.user_id = userdsid.id").select("*")
This get me the last join only works i think it's overrides is there any solution to that

Just as a quick solution... Have you tried to put it in the same method call:
#array = UsersWalletsBalancesFrozen.joins("INNER JOIN userds AS user_to userdsidto ON transactions.user_id_to=user_to.id INNER JOIN userds userdsid AS user_from ON transactions.user_id = user_from.id").select("transactions.*, user_to.username, user_from.username")
?
PS: select('*') will be called by default. No need to explicitly specify it.

Related

MySQL Select and Join - Ambiguous column

I'm trying to join four tables together. The code works fine when I'm only comparing the EVENT_DATA and joining the PERSONA tables as I'm able to get the "Name" column from PERSONA (which doesn't exist in the EVENT_DATA table). However, one of the problems is that this "Name" column also exists in the CUSTOMCAR table, so I can only get one or the other. Additionally, when I tried adding the last join statement, the code wouldn't run at all.
If someone could please help me, that would be great!
$sql = "SELECT * FROM EVENT_DATA
LEFT JOIN PERSONA ON EVENT_DATA.personaId = PERSONA.ID
LEFT JOIN CUSTOMCAR ON CUSTOMCAR.ownedCarId = EVENT_DATA.carId
LEFT JOIN CARCLASSES ON CARCLASSES.store_name = CUSTOMCAR.name
WHERE (EVENT_DATA.EVENTID = '299')";
You should avoid * and use explicit columns list instead:
SELECT EVENT_DATA.personaId, ...
FROM EVENT_DATA
LEFT JOIN PERSONA ON EVENT_DATA.personaId = PERSONA.ID
LEFT JOIN CUSTOMCAR ON CUSTOMCAR.ownedCarId = EVENT_DATA.carId
LEFT JOIN CARCLASSES ON CARCLASSES.store_name = CUSTOMCAR.name
WHERE (EVENT_DATA.EVENTID = '299');
If you have same column name you need to to use aliasing:
SELECT ...
CUSTOMCAR.NAME AS c_name,
PERSONA.NAME AS p_name
...
You could also use Aliasing:
$sql = "SELECT ed.*,
pa.*,
cc.*,
ccs.*
FROM EVENT_DATA AS ed
LEFT JOIN PERSONA AS pa ON ed.personaId = pa.ID
LEFT JOIN CUSTOMCAR AS cc ON cc.ownedCarId = e.carId
LEFT JOIN CARCLASSES AS ccs ON ccs.store_name = cc.name
WHERE (ed.EVENTID = '299')";
Note: Although as suggested by #Lukasz, you should really avoid using wildcard (*), and provide an explicit list of columns in the SELECT clause.

Simple query issue with multiple tables and mismatching IDs

I'm having trouble with a simple MySQL Query.
Here is the query:
SELECT distinct e.E_CODE, s.S_CODE, p.P_ID, p.P_NAME, p.P_FIRSTNAME, p.P_STATUS, e.E_BOSS, tp.TP_TITLE
from event_participation ep, worker p, type_participation tp, event e, section s
where ep.P_ID = p.P_ID
and s.S_ID = e.S_ID
and ep.TP_ID = tp.TP_ID
and e.E_CODE = ep.E_CODE
The problem is that ep.TP_ID sometimes has a value set to zero while tp.TP_ID has nothing with a zero ID. It's auto-increment and starts at 1 and so on.
The result is obviously that this query does not return records when the ep.TP_ID = 0 and there is no match in tp.TP_ID.
So I'm trying to figure out a way to get those results in there anyway. I was thinking of using a LEFT JOIN statement but couldn't figure out a proper way to insert it into the query.
Any advice on this matter would be greatly appreciated.
First of all, I advice you to use some general type for event_participation records without type; But, unless to take that decision, supposing you want to get all matching records between all tables but also get results with no type, you can use the following query:
SELECT DISTINCT e.E_CODE, s.S_CODE, p.P_ID, p.P_NAME, p.P_FIRSTNAME, p.P_STATUS, e.E_BOSS, tp.TP_TITLE
FROM event_participation ep
JOIN worker p ON (ep.P_ID = p.P_ID)
JOIN event e ON (e.E_CODE = ep.E_CODE)
JOIN section s ON (s.S_ID = e.S_ID)
LEFT JOIN type_participation tp ON (ep.TP_ID = tp.TP_ID)
SELECT DISTINCT e.E_CODE
, s.S_CODE
, p.P_ID
, p.P_NAME
, p.P_FIRSTNAME
, p.P_STATUS
, e.E_BOSS
, tp.TP_TITLE
FROM event_participation ep
JOIN worker p
ON p.P_ID = ep.P_ID
JOIN event e
ON e.E_CODE = ep.E_CODE
JOIN section s
ON s.S_ID = e.S_ID
LEFT
JOIN type_participation tp
ON tp.TP_ID = ep.TP_ID;

Rails - How to force associations to use alias table name

p = Patient.find(30)
p.patient_problems
The above code generates the following query
SELECT `patient_problem`.* FROM `patient_problem` WHERE `patient_problem`.`patient_id` = 30 AND (`patient_problem`.`record_status_id` = 1)
But is there any way to assign/use alias table_name like
p.patient_problems(:alias=>'p1') # just for Ex.. This code will not work
p.patient_problems(:alias=>'p2') # just for Ex.. This code will not work
So it will generate the following queries
SELECT `p1`.* FROM `patient_problem` AS `p1` WHERE `p1`.`patient_id` = 30 AND (`p1`.`record_status_id` = 1)
SELECT `p2`.* FROM `patient_problem` AS `p2` WHERE `p2`.`patient_id` = 30 AND (`p2`.`record_status_id` = 1)
Additional Info
My problem is when I try to use joins
p.patient_problems(:all,:joins=>joins)
I get this error
ActionView::Template::Error (Mysql2::Error: Not unique table/alias: 'patient_problem': SELECT `patient_problem`.* FROM `patient_problem` LEFT OUTER JOIN party on party.id = patient_problem.patient_id
LEFT OUTER JOIN party_identifier on party.id = party_identifier.party_id
LEFT OUTER JOIN blood_type on blood_type.id = party.blood_type_id
LEFT OUTER JOIN education_level on education_level.id = party.education_level_id
LEFT OUTER JOIN religion on religion.id = party.religion_id
LEFT OUTER JOIN living_arrangement on living_arrangement.id = party.living_arrangement_id
LEFT OUTER JOIN patient_problem patient_problem on patient_problem.patient_id = party.id and patient_problem.record_status_id = 1
left join (select user_type,username,user_id,auditable_id from (select MAX(id) id from audits where audits.auditable_type = 'PatientProblem' and user_type is not null group by auditable_id ) t inner join audits v on v.id=t.id ) entered_by1 on entered_by1.auditable_id = patient_problem.id
left outer join user user1 on entered_by1.user_id = user1.id
left outer join party as party_user1 on party_user1.id = user1.person_id
LEFT OUTER JOIN patient_patient_search patient_patient_search1 on patient_patient_search1.patient_id = party.id
left join search search1 on patient_patient_search1.patient_search_id = search1.id
and patient_patient_search1.patient_search_id = '75' WHERE `patient_problem`.`patient_id` = 45 AND (`patient_problem`.`record_status_id` = 1) AND ( (patient_problem.occurrence_date > '2013-01-01 00:00:00' and patient_problem.occurrence_date < '2013-06-30 23:59:59' and patient_problem.patient_problem_status_id in (5) and patient_problem.code is not null and patient_problem.code in ('10725009') ) and ( patient_patient_search1.patient_search_id in (75.0) ) ))
Ofcourse I could do some string manipulation on the generated joins query and set alias to patient_problem. But I thought setting alias for associations would be more cleaner since the joins query generated are unpredictable(in my scenario)
I am not sure what the variable joins is or how it was constructed. To alias tables in a join build your query like
Rails 3
PatientProblem.joins("as p1 OUTER JOIN patient_problem as p2 on ...")
or
PatientProblem.find(:all, :joins => "as p1 OUTER JOIN patient_problem as p2 ON ...")
you can make singleton methods for that and write the query one time and use may time like
def self.p1
#your active record query here.
end
and call like
PatientProblem.p1
Update
You can simply change the table name in your code:
Patient.table_name="p2"
I'm not sure if this would break anything else though ... so good luck!
Orignal Answer
One solution may be to define a separate model for each type of patient_problem and then do something like this:
class PatientProblem2 < ActiveRecord::Base
self.set_table_name "p2"
...
end
Another solution may be to use the ActiveRecord query interface which will allows for significant query flexibility:
http://guides.rubyonrails.org/active_record_querying.html
Perhaps you can be more specific on the nature problem you are trying to solve.

Suggestion required resolving an issue with query

My query is as follows:
SELECT collection_content_mappings.tbl_content_common_id
FROM collection_content_mappings Inner Join tbl_content_commons ON collection_content_mappings.tbl_content_common_id = tbl_content_commons.id
INNER JOIN tbl_content_additionals ON collection_content_mappings.tbl_content_common_id = tbl_content_additionals.content_content_code
WHERE collection_content_mappings.collection_id = 1
This part is the problem:
collection_content_mappings.tbl_content_common_id = tbl_content_additionals.content_content_code
The field "collection_content_mappings.tbl_content_common_id" is not the one that need to be equated there; instead I have to take tbl_content_commons.content_common_code from tbl_content_commons where collection_content_mappings.tbl_content_common_id = tbl_content_commons.id . How do I add this to the query above?
Any help is appreciated
You should really rename your tables when you are building the query.
I don't know if I understand properly what you want, but I think that is something like this:
SELECT tbl_content_commons.id
FROM tbl_content_commons
Inner Join collection_content_mappings ON collection_content_mappings.tbl_content_common_id = tbl_content_commons.id
INNER JOIN tbl_content_additionals ON tbl_content_additionals.content_content_code = tbl_content_commons.content_common_code
WHERE tbl_content_commons.id = 1

Struggling with MySQL query

I have the following model:
I've been at this for a while and still don't know how to tackle it properly. Already looked at joining two aliased subqueries, joining two views, and tried a gynormous and ugly all-in one query, none of which worked.
My question is simple:
How can I select deivce_names.name and match them to a model and manufacturer?
SELECT
name, manufacturer, model
FROM
device_names
JOIN devices ON (device_names.id = name_id)
JOIN devices_generic ON (generic_device_id = devices_generic.id)
JOIN device_manufacturers ON (manufacturer_id = device_manufacturers.id)
JOIN device_models ON (model_id = device_models.id)
select
device_names.name as device_name,
device_manufacturers.name as device_manufacturer_name,
device_models.name as device_model_name
from deivce_names
join device on device.name_id = deivce_names.id
join devices_generic on devices_generic.id = devices.generic_device_id
join device_manufacturers on devices_generic.manufacturer_id = device_manufacturers.id
join device_models on device_models.id = devices_generic.model_id
SELECT dm1.manufacturer, dm2.model from device_manufacturers as dm1 join devices_generic as dg on dg.manufacturer_id = dm1.id join device_models as dm2 on dm2.id = dg.model_id join devices as d2 on d2.generic_device_id = dg.id join device_names as dn on dn.id = d2.name_id where name = 'foo'
In the future, you might want to simply put your data into a fiddle and play with it there.