I am trying to achieve a strange query. I have a table like this:
table People
-----------------------
| id | name | family |
+----+------+--------+
| 1 | Bob | Smith |
+----+------+--------+
| 2 | Joe | Smith |
----------------------
I want to return an assoc array like this
id : 1
name : bob
family : smith
familySize : 2
So something like this
"SELECT id, name, family, familySize FROM People"
How can I get the familySize in there? Keep in mind my query may have many families and I want them all to be returned.
Thank you.
The above 2 answers won't work with multiple families.
You can do something like this:
SELECT id, name, family, familySize FROM People p1
JOIN (SELECT COUNT(*) as familySize, family FROM People GROUP BY family) p2
USING(family)
You can do it like this
SELECT id, name, family, count(id) as familySize FROM People
"SELECT id, name, family, count(family) as familySize FROM People group by
family"
I would like to mention here that what if two or three families have the same surname "Smith". It won't give you the desired results.
What I suggest you is while inserting the data in the table assign a family head and all the family members have a field called family_ID has primary key as value of family_head.
This will give you accurate results with 1000's of people. I have made a family portal has over 12k members now and it works fine for me.
Hope it helps.
Related
How can the above table be transformed to give the result below (php mysql)?
Desired Output
| perf_o | names | gender | age |
--------------------------------------
| 28 | John Doe | male | 38 |
| 26 | mary jane | female | 20 |
This table design is a somewhat goofy key/value setup. It's "somewhat goofy" because those setup usually have a master and a detail table, but here the master table is denormalized into the detail table. There doesn't seem to be a performance reason for the denormalization.
So, you need to use a subquery to do this perfectly. The subquery generates the master table.
SELECT DISTINCT names, perf_o FROM tbl
It gives one row for each person in your input table. (This assumes that each person has a distinct value of perf_o; I guess that's true, but you did not say so.)
Then you join that twice to your detail table, once for each value of info.
SELECT master.perf_o, master.names,
gender.d_prov AS gender,
age.d_prov AS age
FROM (
SELECT DISTINCT names, perf_o FROM tbl
) master
LEFT JOIN tbl gender ON gender.perf_o = master.perf_o AND info = 'gender'
LEFT JOIN tbl age ON age.perf_o = master.perf_o AND info = 'age'
Each of the LEFT JOIN operations picks up one of your chosen keys, and associates it with the master table.
This seems complex, but it will do something reasonable for cases where no age or no gender is recorded for the person.
You have presented a problem that's trickier than usual for somebody just starting out with SQL. Please please don't just cut and paste my answer; instead try to understand it.
I've tried a whole slew of examples / answered questions on stackoverflow but I can't seem to accomplish what I need.
I have a PHP / MySQL tool I'm working on to track projects for myself. I thought it'd be a good idea to optimize the largest table right off the hop, so I chose to store ID's in the Project table as opposed to full names. I'm looking to link that ID from the Project table to the actual Name in another table when viewing results via PHP, but of course I want the actual database column to just contain the ID. I believe this is possible, I just can't figure out how to apply it to my situation.
Table - Projects
ID | CustomerID | Summary | Phase
---------------------------------
1 | 61 | Project1 | 3
2 | 42 | Project2 | 3
3 | 33 | Project3 | 5
Table - Customers
ID | CustomerName
--------------------
61 | Customer 1
42 | Customer 2
33 | Customer 3
Right now when I call the "CustomerID" row from the Projects Table, it displays the CustomerID number as expected. I would like it to pull the CustomerName from the Customers table instead, matching the Customers.ID column to the Projects.CustomerID column.
Is this possible? Can anyone point me in the right direction?
Thanks in advanced!
You can try something like this:
SELECT CustomerName FROM Projects
JOIN Customers ON Customers.ID = Projects.CustomerID
WHERE Projects.ID = "1"
I believe something like this should work:
SELECT CustomerName FROM Customers JOIN Projects ON CustomerID = ID;
You are selecting the customername from customers and joining that table with projects where customerid is equal to id.
I have a table where the table has a category field is array value
LIKE :
|-----------------------------------|
|post_id | name | category_id |
-------------------------------------
|1 | test1 | 1,2,45 |
|2 | test2 | 2,7 |
|3 | test3 | 7,13,56 |
|-----------------------------------|
From drop down select box if i select CATEGORY ID 2. i should get the result of TWO ROWS. because post_id 1 and 2 have 2 in category_id. i don't know how to do query for it. i struggled a lot. please help me out. Thanks in advance.
If posts can be in multiple categories, then you should reconsider the use of arrays in the category_id field, and instead use a post/category reference table, with a structure such as:
id postId catId
This way, you can get all posts in category 2 by (lets call this reference table 'PostCats'):
SELECT postId FROM PostCats WHERE catId=2
There is a simple way to sort this out.
You can change the datatype of category_id to SET and using something like this:
SELECT * FROM table WHERE FIND_IN_SET('2', category_id);
Read more: FIND_IN_SET
Also look at flauntster' answer for the most appropriate way to do it.
Alright, I'm not the best with JOIN's and after all these years of working with mySQL you think I would be by now at the least minimally decent. Guess I've never really worked on anything superbly complex til now worth needing to join a table. So here I am, confused ever so slightly in need of a helpful example to get me on a roll, something that's pertinent to my actual data that I can make heads or tales of cause all the reading I'm doing online else where just gives me headaches for the moment. I think I might be stuck on the mythology of JOIN's being a hard thing to do, they don't seem like it but when ever I've tried I fail. So anyway I am working with PHP as my server side coding, and I believe MySQL 5.
So heres the construct to an extent.
I have table information and table connections.
Connections has: member_id, connection_id, active
Information has: firstname, lastname, gender, member_id
I should say the tables contain more data per table, but as I understand it I need write a query that I can use the member_id as the connector/foreign key. Where I can use both sides of the information. I need to know if active is 1, and then I need to know all of the columns above mentioned for information.
I tried
SELECT member_id,
connection_id,
active,
firstname,
lastname,
gender,
member_id
FROM connections, information
WHERE connection.member_id = information.member_id AND
connection.active = 1
and I've tried
SELECT * FROM connections, information
WHERE connection.member_id = information.member_id AND
connection.active = 1
With the first one I get member_id is ambitious which is understandable to a point i think cause of the matching columns between the two tables. Then the second query doesn't server me well as it only results with one person.
My Ultimate goal is to find all the connections for a specific member_id in the connections table, while gathering all the information about those connections from the information table using the connection_id as its the same thing as the member_id in the in the information table.
So in laymans terms if I am not making sense lets say I wanted to list out all my friends in from the DB. My connection table lets me know which people I am connected to where member_id is my id and connection_id is my friends member_id on another table. Hopefully that makes more sense. And this is where I am having trouble with my query and trying to write it correctly. If I could get a working sane sample of that I think I might be able to make better sense of JOIN's doesnt help that I also can't figure out what type of JOIN is best suited for my needs either I suppose.
EDIT....
Ok as per request from comment below. Sample data expected output from tables that look similar to this:
Connections Table
member_id, connection_id, active
1 | 2 | 1
1 | 3 | 1
1 | 4 | 1
1 | 5 | 1
2 | 1 | 1
2 | 5 | 1
3 | 1 | 1
Information Table
member_id, firstname, lastname, gender, ...other unimportant rows for this query
1 | Chris | Something | m | ....
2 | Tony | Something | m | ....
3 | Brandon | Something | m | ....
4 | Cassie | Something | f | ....
5 | Jeff | Something | m | ....
6 | John | Something | m | ....
now from the connections table I need to gather all the connection_id's associated with my member_id where active is 1 then from the information table gather everyone firstname, lastname, gender.. Now I know I can do this 2 step where I pool all the connection_id's from connections then run them through a loop of some sort and one by one get the resulting id's from the first query but to me that seems a bit obscure and process intensive which I want to avoid, which brings me here.. Currently from my original query posted to the many shared thus far trying to help my results are to the effect of
1 | Chris | Something | m | 2
1 | Chris | Something | m | 3
1 | Chris | Something | m | 4
1 | Chris | Something | m | 5
what I'd like to see returned is something like
2 | Tony | Something | m
3 | Brandon | Something | m
4 | Cassie | Something | f
5 | Jeff | Something | m
After looking at this I suppose I would also need to know the friendID column that matches my member_id as well but thats something to figure out after this initial hurdle
The error is in your WHERE Clause because instead of Connections you wrote it Connection which then the server generates the error.
...
WHERE connection.member_id = information.member_id AND
connection.active = 1
try this:
SELECT a.Member_ID,
a.FirstName,
a.LastName, a.gender,
b.Connection_ID
FROM Information a INNER JOIN Connections b
on a.Member_ID = b.Member_ID
WHERE b.`Active` = 1
UPDATE
if that's the case then you will most likely have a SELF JOIN
SELECT DISTINCT b.Connection_ID,
c.*
FROM Information a INNER JOIN Connections b ON
a.Member_ID = b.Member_ID
INNER JOIN Information c ON
b.Connection_ID = c.Member_ID
WHERE b.`Active` = 1
AND a.Member_ID = 'ID HERE' -- If you want to get for specific member
The error in the first is "ambiguous" not ambitious. Ambiguous means that the SQL engine doesn't know which column you are talking about, because you have two columns with the same name (different tables but still).
You can fix that by specifying the table name along with the column name where you list the columns for select.
For example
SELECT connections.member_id, connection_id, active, firstname, lastname, gender, information.member_id FROM connections, information WHERE connections.member_id = information.member_id AND connections.active = 1
The problem with returning only one suggests that there is only one record that matches your query but it's hard to guess.
Try changing to:
SELECT * FROM connections c JOIN information i ON i.member_id = c.member_id WHERE c.active = 1
Try this:
SELECT *
FROM information
LEFT OUTER JOIN connections
ON information.member_id = connections.member_id
WHERE connections.active = 1;
You're joining on the wrong tables. You said:
where member_id is my id and connection_id is my friends member_id on another table
Then, what you have to match is connections.connection_id with information.member_id. The simplest solution is:
select c.member_id, c.connection_id, c.active from connections c
join information i on c.connection_id = i.member_id
where c.active = 1 and c.member_id = #yourId
That's all :)
I have 3 mysql tables: events, artists and (artist) descriptions. All of them are in many-to-many relations.
Table 'events':
ID | eventTitle | etc.
-----------------------
1 | event 1 |
2 | event 2 |
etc.
Table 'artists':
ID | artistName | etc.
-----------------------
1 | artist 1 |
2 | artist 2 |
etc.
Table 'descriptions':
ID | artistDesc | etc.
----------------------------------
1 | artist 1 description 1 |
2 | artist 1 description 2 |
3 | artist 2 description 1 |
4 | artist 2 description 2 |
5 | artist 3 description 1 |
etc.
I made also junction tables events_artists and artists_desctriptions. Both of them have only 2 foreign keys and serve only for linking event, artist and description IDs.
Notice in my descriptions table - each artist can have many descriptions. That actually means that each description belongs to only one specific event. =)
If I do a query like this:
$q = "SELECT
events.*,artists.*,descriptions.*,events_artists.*,artists_descriptions.*
FROM
events,artists,descriptions,events_artists,artists_descriptions
WHERE
events.eventID = events_artists.eventID AND
events_artists.artistID = artists.artistID AND
artists.artistID = artists_descriptions.artistID AND
artists_descriptions.descID = descriptions.descID";
I will get all the descriptions for a particular artist. But none of descriptions will be aware which event they belong to...
What I want to display to user is something like this:
EVENT 1
artist 1 (artist 1 description 1)
artist 2 (artist 2 description 2)
EVENT 2
artist 3 (artist 3 description 6)
artist 1 (artist 1 description 3)
etc.
Should I make a junction table for event-description relation? If I do, I don't know exactly how to use it, uff! =)
Or maybe my problem isn't solvable with a simple query? Should I do something with php too? Sorry but I am totally confused =)
I hope I managed to explain my problem properly...
Thanks in advance for any help!
you should combine events_artists & descriptions tables to have only 1 table that links artist to an event and a description.
Can you modify the tables you already have? If so, and if each artist description can have only one artist and one event, then I would modify your schema to be:
Table event as is.
Table artists as is.
Table descriptions:
ID | artistDesc | artistId | eventId | etc.
------------------------------------------------------------------
1 | description of artist at event | 4 | 1 | ...
Then you can select all descriptions for an event with:
$query = "SELECT
events.*,artists.*,descriptions.*
FROM
events,artists,descriptions
WHERE
artists.artistID = descriptions.artistID AND
events.eventID = descriptions.eventID AND
events.eventID = $eventIdYouWant";
You can change the last row of that query to either events.event_name = $eventNameYouWant or artists.artist_name = $artistNameYouWant and it will work the same as if you were directly specifying the id.
you have already said its a relation between 3 tables .. so i think the answer is pretty obvious .. you need to have 1 table artist_id , event_id and description_id in ONE table instead of diving that into two tables like u have now.
I think you should alter your table structure, if you can.
It will result in a neater design.
Make a table, artist_event_description which contains all the IDs as foreign keys, instead of the two junction tables, it will help you to find out, to which event and artist a description belongs.
Another thing you can do is to include two more columns in the Description table, eventId and artistId (these will be foreign keys) and remove the junction tables. This way you will directly get all the information you need by just doing a SELECT over the description table.