Propel 2 double join on custom field - php

I'm trying to create a query with propel that joins a first table called Entry with a second table called Company that have 3 fields related to a third table called User.
Entry
id
field1
field2
company_id
Company
id
field1
field2
user_id1
user_id2
user_id3
User
id
name
surname
team
I want to be able to join Entry to Company by company_id and then join to the table User using the field userid1.
I tried different ways like
EntryQuery::create()->joinWith('Company')->joinWith("User")
but I get and error saying that Entry has no relation with user
or
EntryQuery::create()->useCompanyQuery()->joinWith("User")->endUse()
but I still get an error that Company has no relation with User, even though all the user fields in Company have a relation with User in the database.
There is any way to specify the field on the join?

I finally found a way to do it, I'm not sure if it's the best one but works.
EntryQuery::create()
->useCompanyQuery()
->innerJoinUserRelatedByUserId1()
->endUse()
->with("Company")
->with("UserRelatedByUserId1")
This hydrates all the relations.

Related

PHP function to return data from database as table with table relationships

I have a requirement for a PHP function that takes table or tables and the required columns from those db tables and returns a html table containing the data. I know how to do this for one table but am struggling with how to make this more dynamic
My thinking for one table would be to have a function that takes the table name and then an array of columns and then just selects the data from the table and then loops through it constructing the data as html and then return that from the function.
As an example my database has two tables; users and orders
users
|----------------------------|
|user_id|first_name|last_name|
|-------|----------|---------|
orders
|----------------------|
|order_id|user_id|total|
|--------|-------|-----|
Now with the function discussed above it would be easy to generate a table for all the users or orders but what I would like to do is have a function where I could dynamically join tables and for example list all users and the number of orders they've made or list all orders from user x. I know that this would be possible with many different functions but I'm really interested in developing a way of doing this dynamically and basically building all the relationships somehow in the program and then be able to call one function and request columns x,y and z
My thinking so far would be (again for this example) somehow define that number of orders for user i = count(order_id) where user_id = i
Hope this makes sense and thank you in advance
The INFORMATION_SCHEMA.KEY_COLUMN_USAGE table can be used to find all foreign key relationships from a particular table to other tables, e.g:
SELECT `TABLE_NAME`,
`COLUMN_NAME`,
`REFERENCED_TABLE_NAME`,
`REFERENCED_COLUMN_NAME`
FROM `INFORMATION_SCHEMA`.`KEY_COLUMN_USAGE`
WHERE `TABLE_SCHEMA` = SCHEMA() -- current schema
AND `REFERENCED_TABLE_NAME` IS NOT NULL
AND `TABLE_NAME` = 'orders'; -- name of table to get relationships to other tables
This should return something like the following:
+--------------+-------------+-----------------------+------------------------+
| TABLE_NAME | COLUMN_NAME | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+--------------+-------------+-----------------------+------------------------+
| orders | user_id | users | user_id |
+--------------+-------------+-----------------------+------------------------+
The above can be done in PHP and the results can then be iterated over to dyamically construct a query that selects from those tables, joining on the listed columns. Will leave that part as an exercise ;-)
You wouldn't need to make a function to grab data from first table then loop around them and get data from the second table.
SQL can do this for you with 1 hit on the database.
All what you need to do is join the two tables, and grab the data you want..
If I understood what you need right, you want to grab all users id from the first table, and get their order count from the second table.
A simple join or selecting from both table could do that, and I suggest something like:
Select a.user_id, b.count(order_id)
FROM table1 as a, table2 as b
WHERE a.user_id = b.user_id
Group By a.user_id
Or you could join the tables and do a similar task.
I am assuming you're gonna access database from PHP code, so try that, and give me back your feedback.
This is easy to implement but we have to fix few things.
Our requirement:
1. Identify Tables according to column name.
2. How we can Join those tables.
3. How to resolve ambiguity of columns.
Solution:
Unique column name for each field or no table has duplicate column name.
To achieve it we should have fix table prefix for each table.
for example:
your column name could be odr_orderid and usr_orderid.
Now by identifying unique prefixes, we can identify tables.
Now issue arises how to join these tables
To resolve it:
Create an another table strong JOIN keys and JOin type Left, right,inner or full.
Thats all Now you can make the query as you want.

Performing a relational Query and selecting distinct records by the combination of two columns in MySql

I have two tables in my database, users and user activities, The user table has id, first_name,last_name and other fields, the user activities table has, id, user_id (foreign key --> from the users table) and project id. I want to select distinct user names (combination of first and last name) where project_id is 1.
If I write this as a simple query it works fine, the query I wrote was:
SELECT DISTINCT users.first_name,users.last_name,`user_activities`.user_id FROM `users`
JOIN `user_activities`
ON users.id=`user_activities`.user_id
WHERE project_id=2;
How do i perform this query in YII?
There is two approaches.
Simple Query Builder
See this.
2) Relations to user table on user activities.
See this.
And at least, give it a try. And update, where you get stuck.

How to solve this perticular query in MySql?

Problem Statement To Solve:
You need to store employee information (name, age, gender and address) and Project information (name, client name, client city) in database. Employees can work on multiple projects and a project can have multiple employees. Some employee might not be on any project.
Please create table structure for this and necessary constraints, don’t use create table query just structure is important and show primary key and data type of each column.
For above scenario write a query for following case:-
To get list of projects, For each project the details needed in the list are-project name, client name, no. of employee working on project.
I little bit understand that there is problem in table 1 that is Project table because it's not normalized
Can’t make much suggestions about constraints or keys, but
definitely Employee and Projects tables need to be primary keys as Employee ID and Project ID respectively,
the gender in employees table could be enum.
Project_employees table is suggested to have a primary key as well, so it can uniquely identify a record in case there are multiple entries of same project or employee ids. That way there won’t be a need of using both of these columns in criteria.
employee
id|name| age| gender| address
client
id|name|city
project
id| name| client_id(FK client.id)
project_employee_mapping
employee_id (FK employee.id) | project_id (FK project.id)
Query:
SELECT p.name, c.client_name, COUNT(pem.employee_id)
FROM project p, project_employee_mapping pem, client c
WHERE pem.project_id = p.id
AND c.id = p.client_id
GROUP BY p.id

MySQL - Database design - separate tables for users and profile

From what I've been reading online, I understood that it's better to split the data into more tables, if possible because of the access times.
Right now I have a table in which I am storing usernames, passwords and join date
This is how my table looks:
'user'
'user_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
user_username VARCHAR(80) NOT NULL,
user_password VARCHAR(255) NOT NULL,
user_join_date INTEGER UNSIGNED NOT NULL,
PRIMARY KEY (user_id) ');
I am trying to create a new table called profiles in which I want to store first name, last name, email, age and gender. What I think is that I need a one-to-one relationship, so I should be using the user_id but I'm not really sure how to implement it.
Should I create another table called profiles with
profiles
profiles_id
first_name
last_name
email
age
gender
and another one which should be the relationship ? e.g.
user_profiles
----------
user_id
profiles_id
Is this right? How would the SQL look for the user_profiles?
Thanks
Don't split the tables. Just add the new columns to your existing user table. You might find later on that splitting tables is a good idea based on actual queries and usage patterns but until you have that kind of data, keep things simple.
If you must create a profile table, don't create a user_profiles table. That would allow an m-to-n relationship which is probably not what you want. A simple user_id column in profiles is better. In fact, it could be both a foreign key and the primary key to make sure that each user row only have one and only one profile row (although by splitting the tables you might still have a user with no profile).
Usually, you create an association table, like user_profiles you have described when one user could have more than one profile, and/or one profile could belong to one or more user.
As you have said, here you have a one-to-one relationship between user and profile. So, you can simply add a user_id column to your profile table, and define it as a foreign key to user table.
Then, a simple JOIN will allow you to query both tables at the same time:
SELECT u.*, p.*
FROM user u
JOIN profile p ON u.user_id = p.user_id
Add a new field in the User table, ProfileId, and set it as Foreign Key (FK). Each time you create a User, you have to assign to it a profile (which will be the ProfileId PK from profile table).
If you want to see also the profile information of a user, you have to do a join
Select username, first_name,second_name
From user u, profile p
Where u.profileId = p.profileId
this
user_profiles
----------
user_id
profiles_id
is used in a many-to-many relationship. By example, you want to assign to an admin some privileges, but those privileges can be also assigned to more admins. Then, you have to create a 3rd table to solve this problem. Here is an example, but you don't need to do this.
You could add a user_id field to your profiles table and JOIN the tables on user_id.
SELECT user.user_username, ..., profiles.first_name, ...
FROM user
INNER JOIN profiles
ON user.user_id = profiles.user_id
This should fetch data combining information from those rows where the JOIN condition is met (i.e. user.user_id = profiles.user_id).
It is true that having more than one tables is a good idea. I am not sure what you mean about access time, but there are other advantages.
- Your users database containing passwords etc is "sacred", you never change its structure and you limit the rights to it (read, write) to the strict minimum.
- You can then have several "satelites" tables such as profiles, private messages, etc which are more flexible, less sensitive and which you can change all the time.
About your question per se, there is no need for a separate table with the relationships. In fact is a very bad idea which will complicate your queries and doesn't have any advantage. Instead, in your profiles database you will have one column that refers back to the user id.
users
--------
id
user_name
email
password
users_profiles
---------
id
user_id
favourite_animal
Table user
user_id |user_username |user_password |user_join_date |profile_id
Table profile
profile_id |first name |last name |email |age |gender
When selecting a user by user id:
SELECT u.*, p.* FROM user AS u INNER JOIN `profile` AS p ON u.profile_id = p.profile_id WHERE u.user_id = 1
But a user should only one gender, one age, one name and surname. Maybe e-mail adresses might be many. I suggest you there is no need to join tables which have a 1-to-1 relation. Instead merge those tables.

Php mysql query for data from two tables

i have two tables in my database. table A is USERS and table B is relations, and the following are their columns
USERS(username, avatar, specialty) and RELATIONS(username1, username2, reldir)
RELATIONS stores the relationship between users, that is if, username1 is following username2, reldir = F, and if they are both following each other, reldir=FB and vice versa, this part has worked very well but
i need to query these tables so that i return a list of users from USERS which for example user A doesnt follow but have the same specialty as A...
i tried this, but its not working well ...
$spec = the specialty of user A
SELECT a.username, a.avatar, a.specialty FROM users a, relations b WHERE a.username!=b.username2 AND (b.reldir!='F' OR b.reldir!='FB') AND a.speciality ='$spec'
the query to me seems logically correct but i could be wrong. i need help
You need to add some keys for your tables, because you have two different tables and they doesn't linked.
For example, table USERS:
id (as primary_key), username, avatar, specialty
Table RELATIONS:
user_id, username2, reldir
user_id - it is field "id" from table USERS (instead your "username1")
Then you will be able create a query like this:
SELECT a.*
FROM users a, relations b
WHERE a.id = b.users_id
AND (b.reldir != 'F' OR b.reldir != 'FB')
AND a.speciality = '$spec'
ps: if I understood your question in the right way)

Categories