I have been using this site for years now and this is the first time I'm asking a question here, so kinda scared right now :D
Here's what my problem is, I have got two tables. In table_a I got three columns and in table_b I got 5. So the setup right now looks something like this:
table_a
| r_id | foo | bar |
+------+-------+-----+
| 1 | dude | 5 |
+------+-------+-----+
| 2 | homie | 6 |
+------+-------+-----+
| 3 | bro | 7 |
+------+-------+-----+
table_b
| id | ada | rea | lm | cor |
+----+-------+-----+------+------+
| 5 | ching | ink | jk | 32.4 |
+----+-------+-----+------+------+
| 1 | momo | pal | lmao | 95.5 |
+----+-------+-----+------+------+
| 6 | mama | pen | lol | 26.9 |
+----+-------+-----+------+------+
| 4 | chac | pin | fun | 91.2 |
+----+-------+-----+------+------+
| 7 | chim | lap | funk | 82.4 |
+----+-------+-----+------+------+
| 9 | cho | kil | fin | 38.1 |
+----+-------+-----+------+------+
Now what I'm trying to do is to get all the data from table_a and then only get lm from table_b. I'm getting all the data from table_a like this:
SELECT r_id, foo, bar from table_a
I need to use the ids I get from bar column to get lm from table_b. So is there a way I can pass an array to only get the data based on the ids in an array? If not, then what would be the most efficient way to get those?
The output I'm expecting is jk, lol, funk.
Would appreciate any help, thanks!
You should be looking at using a JOIN to link the two tables together in 1 query...
SELECT r_id, foo, bar, lm
FROM table_a
JOIN table_b on bar = id
try inner join
SELECT a.r_id, a.foo, a.bar, b.lm from table_a as a inner join table_b as b on b.id=a.bar
Why not join?
select group_concat(lm) as lm_list
from table_b b
inner join table_a a on b.id = a.bar
You can use the GROUP_CONCAT() function, with this you would get jk, lol, funk otherwise you would get 3 rows each of one lm value,
For that you can try WHERE IN feature of SQL.
SELECT lm from table_b WHERE id IN(ARRAY_OF_IDS)
Or you can also use join to achieve this
Select tale_a.*, tale_b.lm from tale_a inner join table_b ON tale_a.bar=tale_b.id
I assume that you have array of IDs having IDs.
So first make a comma separated string of that array of IDs like this:
ids_str = implode("," $ARRAY_OF_IDS);
and then use that ids_str in IN os mysql query like below:
SELECT lm from table_b WHERE id IN( ids_str )
You can use INNER JOIN
SELECT tale_a.r_id, tale_a.foo, tale_a.bar ,table_b.lm
FROM tale_a
INNER JOIN table_b
ON tale_a.bar=table_b.id
Note: It returns all columns from table_a and only one column from table_b
Resultant Output:
| r_id | foo | bar | lm |
+------+-------+-----+-----+
| 1 | dude | 5 | jk |
+------+-------+-----+-----+
| 2 | homie | 6 |lol |
+------+-------+-----+-----+
| 3 | bro | 7 |funk |
+------+-------+-----+-----+
Related
I have 3 tables in mysql, table A, B and C.
C has a relationship with B (b_id) and B has a relationship with A (a_id).
that means A has many B, and B has many C. To select all, I have this query:
SELECT a.id, a.name, a.text, b.ptext, c.ctext
FROM tableA as a
JOIN
tableB as b
ON
(b.p_id = a.id)
JOIN
tableC as c
ON
(c.p_pid = b.pid)
WHERE a.id = 1
which returns this:
| ID | NAME | TEXT | BTEXT | CTEXT |
|----|-------|--------------|--------|--------|
| 1 | page1 | futkdvthsa_1 | post_1 | thing1 |
| 1 | page1 | futkdvthsa_1 | post_2 | thing2 |
| 1 | page1 | futkdvthsa_1 | post_2 | thing3 |
is there any chance of getting something like this:
id | name | text | posts
1 | page1 | futkdvthsa_1 | posts (post_1 = ( thing1 ), post_2 = ( thing2, thing3 ) )
Sigle queries for each table or would need to do in a php way?
P.S. this would be for a wordpress plugin with custom tables.
I guess the simplest way to do this is by doing it with php.
You would have to use a stored procedure to concatenate your fields with sql.
I have 2 queries which gives all records(including the booked ones) and gives out booked records only. I wanted to subtract the two tables so that it only shows the unbooked records, here are the example of the query results:
Query 1:
+--------+--------+
| Number | AreaNo |
+--------+--------+
| 6 | A |
| 6 | B |
| 6 | C |
| 7 | A |
| 7 | B |
+--------+--------+
Query 2:
+--------+--------+
| Number | AreaNo |
+--------+--------+
| 6 | B |
| 6 | C |
| 7 | B |
+--------+--------+
Desired Results:
+--------+--------+
| Number | AreaNo |
+--------+--------+
| 6 | A |
| 7 | A |
| 7 | C |
+--------+--------+
I know that I can't use MINUS in mySQL but I'm not sure that LEFT JOIN works in this situation. If this doesn't work, is it possible to work on the where clause?(Like if the number match, it only clear out the one with matching AreaNo). I tried this with two AND clause and it doesn't work. It clears out the results that doesnt fit either criteria. I have been doing researches over a week and nothing works. Please help, I am really desperated.
Query 1:
SELECT bookingListNo,
areaNo
FROM BookingList,
BookingArea,
BookingLocation
WHERE bookingListNo NOT IN (SELECT bookingListNo
FROM Booking
WHERE bookingAreaNo IS NULL) AND
BookingList.bookingLocationNo = BookingLocation.bookingLocationNo AND
BookingLocation.BookingLocationNo = BookingArea.bookingLocationNo
Query 2:
SELECT bookingListNo,
areaNo
FROM Booking,
BookingArea
WHERE Booking.bookingAreaNo = BookingArea.bookingAreaNo
This is how you do it.
SELECT Q1.Number,
Q1.AreaNo
FROM Query1 Q1
LEFT JOIN Query2 Q2
ON Q1.Number = Q2.Number AND
Q1.AreaNo = Q2.AreaNo
WHERE Q2.Number IS NULL AND
Q2.AreaNo IS NULL
LEFT OUTER JOIN will do the trick
SELECT *
FROM TABLE1 t_1 LEFT OUTER JOIN TABLE2 t_2
ON t_1.AreaNo = t_2.AreaNo ;
Check out this article for reference: http://www.sitepoint.com/understanding-sql-joins-mysql-database/
I'm guessing a RIGHT JOIN would do the trick.
Not exactly sure what your tables are like, but if you are joining a table with unbooked data to one that has all of our items, then you could do a query like this:
SELECT *
FROM all_items
RIGHT JOIN unbooked_data ON all_items.item_id = unbooked_data.item_id
When you RIGHT JOIN it only selects the items that are in the table you are joining on that have matches in the table being joined to. This should allow you to select unbooked data. If this doesn't fit your situation, including your queries in your question might help us answer your problem more directly.
mysql> SELECT tabl1.number,tabl1.areano FROM tabl1 LEFT JOIN tabl2 using(number,
areano) WHERE tabl2.number IS NULL; ;
+--------+--------+
| number | areano |
+--------+--------+
| 6 | A |
| 7 | A |
+--------+--------+
I have 3 tables, structured like so:
TABLE A:
ID | PCID | ACTIVE | COHORT | WEEKLY_MEETING_TIME | FYE_ID | RC | AGREEMENT_SIGNED | RELEASE_SIGNED | NOTES | FACULTY_ADVISOR
TABLE B:
ID | QUARTER | OFFICE | WRITING_CENTER | etc.. | etc.. | etc.. |
TABLE C:
ID | QUARTER | WEEK | EMAIL | etc.. | etc.. | etc.. |
The common element between all 3 tables is the ID field.
I need to SELECT from all 3 tables, and have each row represent one ID and all the values associated with that ID.
So, for example, each output row should look like a combination of the three tables:
RESULTS:
ID | PCID | ACTIVE | COHORT | WEEKLY_MEETING_TIME | FYE_ID | RC | AGREEMENT_SIGNED | RELEASE_SIGNED | NOTES | FACULTY_ADVISOR | QUARTER | OFFICE | WRITING_CENTER | etc.. | etc.. | etc.. | WEEK | EMAIL | etc.. | etc.. | etc.. |
I have no idea how to structure a query like this. I suspect it involves using JOINs but my attempts have proved futile.
how can I combine the data from 3 tables, based on shared ID field?
SELECT * FROM TABLEA
INNER JOIN TABLEB ON TABLEA.ID = TABLEB.ID
INNER JOIN TABLEC ON TABLEA.ID = TABLEC.ID
If you don't need all the values substitute the "*" with the names of the fields you need (ex. TABLEA.ID, TABLEB.QUARTER, TABLEC.WEEK...)
NATURAL JOIN works in MySQL:
select * from A natural join B natural join C
Try this :
SELECT / WHAT YOU NEED TO SELECT - NOT * !!!/
FROM TABLEA
INNER JOIN TABLEB USING (ID)
INNER JOIN TABLEC USING (ID)
I have two tables : ticket & history_ticket
Table ticket :
ticket_id | ticket_desc
1 | software
2 | hardware
3 | other
Table history_ticket :
history_id | ticket_id | message | status
1 | 1 | text | process
2 | 2 | text | solve
3 | 3 | text | process
4 | 3 | text | solve
I want result like this
ticket_id | ticket_desc | status
1 | software | process
2 | hardware | solve
3 | other | solve
I've tried various joins and subselects, but no luck
Any help/directions will be much appreciated!
UPDATE : How if i change the result, like this
ticket_id | ticket_desc | last_status | count_message
1 | software | process | 1
2 | hardware | solve | 1
3 | other | solve | 2
Try this:
SELECT
t.ticket_id,
ticket_desc,
ht.status
FROM ticket AS t
INNER JOIN history_ticket AS ht ON t.ticket_id = ht.ticket_id
INNER JOIN
(
SELECT ticket_id, MAX(history_id) maxid
FROM history_ticket
GROUP BY ticket_id
) AS ht2 ON ht.history_id = ht2.maxid;
SQL Fiddle Demo
This will give you:
| TICKET_ID | TICKET_DESC | STATUS |
-------------------------------------
| 1 | software | process |
| 2 | hardware | solve |
| 3 | Problem | solve |
UPDATE 1
To get the count of messages for each ticket, you can simply include COUNT(history_id) AS sum_message in the subquery like this:
SELECT
t.ticket_id,
ticket_desc,
ht.status,
ht2.sum_message
FROM ticket AS t
INNER JOIN history_ticket ht ON t.ticket_id = ht.ticket_id
INNER JOIN
(
SELECT
ticket_id,
MAX(history_id) maxid,
COUNT(history_id) AS sum_message
FROM history_ticket
GROUP BY ticket_id
) AS ht2 ON ht.history_id = ht2.maxid;
Updated SQL Fiddle Demo
This will give you:
| TICKET_ID | TICKET_DESC | STATUS | SUM_MESSAGE |
---------------------------------------------------
| 1 | software | process | 1 |
| 2 | hardware | solve | 1 |
| 3 | Problem | solve | 2 |
Update 2
If you want to select names for the ids divisi_id, for simple values, you can use the CASE expression for this:
SELECT
t.ticket_id,
ticket_desc,
CASE
WHEN t.divisi_id = 101 THEN 'Divisi A'
WHEN t.divisi_id = 102 THEN 'Divisi B'
END AS 'Divisi',
ht.status,
ht2.sum_message
FROM ticket AS t
INNER JOIN history_ticket ht ON t.ticket_id = ht.hticket_id
INNER JOIN
(
SELECT hticket_id, MAX(history_id) maxid, COUNT(history_id) AS sum_message
FROM history_ticket
GROUP BY hticket_id
) AS ht2 ON ht.history_id = ht2.maxid;
Updated SQL Fiddle Demo
This will give you:
| TICKET_ID | TICKET_DESC | DIVISI | STATUS | SUM_MESSAGE |
--------------------------------------------------------------
| 1 | software | Divisi A | process | 1 |
| 2 | hardware | Divisi B | solve | 1 |
| 3 | Problem | Divisi A | solve | 2 |
For multiple values, you can put them in a temp table, or you can select them in a subquery and join the table to get the name like this:
SELECT
t.ticket_id,
ticket_desc,
d.Divisi,
ht.status,
ht2.sum_message
FROM ticket AS t
INNER JOIN history_ticket ht ON t.ticket_id = ht.hticket_id
INNER JOIN
(
SELECT hticket_id, MAX(history_id) maxid, COUNT(history_id) AS sum_message
FROM history_ticket
GROUP BY hticket_id
) AS ht2 ON ht.history_id = ht2.maxid
INNER JOIN
(
SELECT 101 AS divisi_id, 'Divisi A' AS Divisi
UNION ALL
SELECT 102 , 'Divisi B'
... -- here you put other values or you can join a temp table instead
) AS D ON t.divisi_id = D.divisi_id;
Updated SQL Fiddle Demo
select distinct ticket.ticket_id, ticket.ticket_desc, history_ticket.status
from ticket
join history_ticket on ticket_id
This, as far as I remember, will choose a description and status at random if you have more than one. If you want to apply a specific rule to which one to pick, give more info and we can help you on that.
Try
SELECT DISTINCT
tk.ticket_id,
tk.ticket_desc,
ht.status
FROM ticket tk JOIN history_ticket ht ON tk.ticket_id = tk.ticket_id
ORDER BY tk.ticket_id
Try,
Select distinct t.ticket_id, t.ticket_desc, h.status
from ticket t, history_ticket h
where t.ticket_id = h.ticket_id
order by t.ticket_id
I will try to be as explanatory as possible regarding my question. I am using MYSQL/PHP to fetch data from two tables with the structure looking like the following:
table A
+---------+------------+
| userid | username |
+---------+------------+
| 1 | john |
| 2 | doe |
| 3 | lewis |
+---------+------------+
table B
+---------+------------+-----------+
| id |from_userid | to_userid |
+---------+------------+-----------+
| 1 | 1 | 3 |
| 2 | 3 | 2 |
| 3 | 1 | 2 |
| 4 | 2 | 1 |
+---------+------------+-----------+
Am trying to achieve the following:
+---------+------------+----------------------+
| id |sender username| receiver username |
+---------+------------+----------------------+
| 1 | john | lewis |
| 2 | lewis | doe |
| 3 | john | doe |
| 4 | doe | john |
+---------+------------+----------------------+
As you can see, instead of returning the sender or receiver user id, I am returning their username according to Table A.
can I use left or right joins in this scenario? Thanks in advance
Try this
SELECT b.id, sender.username AS sender_username, receiver.username AS receiver_username
FROM tableB AS b
JOIN tableA AS sender ON b.from_userid = sender.userid
JOIN tableA AS receiver ON b.to_userid = receiver.userid
Inner joins would work fine, you just need to do two of them...
Left and right joins are only needed when you want to get all records from one table and some from another table. In this case you have two distinct relationships thus the need for two joins. My MySQL skills are a bit rusty so I don't know if ' or [ are used as separators on the table/field names with spaces.
Select t1.ID, T1.userName as 'Sender userName', T2.username as 'Receiver username'
FROM [Table A] A
INNER JOIN [Table B] T1
on T1.from_userid = A.userID
INNER JOIN [Table B] T2
on T2.to_userid = A.userID