I had create two table (Table A and Table B) and try using INNER JOIN both table but the result will be in different row even the ID is same.
$sql = "SELECT * FROM Table A INNER JOIN Table B ON Table A.ID = Table B.ID";
Is there any mysql select to extract all the value with same ID in one row as shown in 'Result' table?
Code:
$sql =
"SELECT GROUP_CONCAT(ITEM1), GROUP_CONCAT(ITEM2)
FROM Table A INNER JOIN Table B
ON Table A.ID = Table B.ID
WHERE Table A.ID = Table B.ID ";
Image
You must group by id, type and use group_concat() only for the item columns.
From your sample data it seems like one of item1 or item2 in each row is null.
If this is the case then:
select
a.id, a.type,
group_concat(coalesce(b.item1, b.item2) order by b.sub_id) item
from tablea a inner join tableb b
on b.id = a.id
group by a.id, a.type
See the demo.
If they can be both null or both not null:
select
a.id, a.type,
group_concat(concat_ws(',', item1, item2) order by b.sub_id) item
from tablea a inner join tableb b
on b.id = a.id
group by a.id, a.type
See the demo.
Results:
| id | type | item |
| --- | --------- | --------------------------- |
| 1 | FRUIT | BANANA,PINEAPPLE,WATERMELON |
| 2 | VEGETABLE | SPINACH,CARROT |
| 3 | MEAT | CHICKEN |
Related
I have three tables, with the following schema;
Table A
id
b_id
amount
Table B
id
amount
Table C
id
a_id
fee_amount
Tables A and B are related directly, however, table C has a_id that may be NULL.
I am trying to put together an SQL query to return the rows whose value of A.amount != B.amount + C.amount.
So far I have this;
SELECT a.*
FROM a
LEFT OUTER JOIN b ON b.id = a.b_id
LEFT OUTER JOIN c ON c.a_id = a.id
WHERE a.amount > 5000 AND a.amount != (b.amount + c.fee_amount)
With a simple dataset like this;
Table A
| id | b_id | amount |
|----|------|--------|
| 1 | 1 | 50000 |
Table B
| id | amount |
|----|--------|
| 1 | 5000 |
Table C
| id | a_id | fee_amount |
|----|------|------------|
| 1 | 1 | 7000 |
And the query returns zero results. I'm pretty I've missed something, just not sure what it is.
I think you need to handle the NULLs by treating them as 0 - eg:
SELECT a.*
FROM a
LEFT OUTER JOIN b ON b.id = a.b_id
LEFT OUTER JOIN c ON c.a_id = a.id
WHERE a.amount > 5000 AND a.amount != (IFNULL(b.amount, 0) + IFNULL(c.fee_amount,0))
First, if only C can have the NULL value, then you are better off using the LEFT JOIN only for that table:
SELECT a.*
FROM a JOIN
b
ON b.id = a.b_id LEFT JOIN
c
ON c.a_id = a.id
WHERE a.amount > 5000 AND
a.amount <> (b.amount + COALESCE(c.fee_amount, 0)) ;
However, normally you have secondary tables like this because the tables can have multiple rows per a_id. If that is the case, you need some sort of aggregation.
i have 2 tables A and B like below
Table A
+---------+--------+
| query | status |
+---------+--------+
| number1 | solved |
+---------+--------+
table B
+----+---------+---------+
| id | query | status |
+----+---------+---------+
| 1 | number1 | started |
| 2 | number1 | working |
| 3 | number1 | solved |
+----+---------+---------+
how do i check whether the latest status of table B is equal to status of Table A
i have tried first getting latest status for table 2 but i am unable to get so
select number ,max(status),max(id)
from Table B
group by number
order by max(id) asc
Here is a simple solution relying on sorting by ID and getting only first row in a sub-query. It will only returns rows that has a match between the two tables.
SELECT a.*
FROM tableA a
JOIN (SELECT query, status
FROM tableB
ORDER BY ID desc
LIMIT 1) b ON a.query = b.query AND a.status = b.status
use join and subquery
select a.* from
tablea a join
(
select * from table_name t1
where id =( select max(id) from table_name t2 where t1.query=t2.query)
) b join on a.query=b.query and a.status=b.status
select *
from A a
inner join B b on b.query = a.query
inner join
(select max(id) id, query
from B
group by query) gq on gq.id = b.id and gq.query = b.query
where a.status = b.status
Just stumped on syntax for this...
I have Two tables in mysql & I need to fetch records from Table A when following criteria are met:
1) Name in Table A matches the name in Table B
AND
2) The price for the most recent day in Table B is less than the record in Table A
So...running the query on example tables below would fetch me these two records:
03-17-2019 Bob 8
03-20-2019 John 10
Essentially, I need to evaluate each row in Table A, check the matching name in Table B that has the most recent date relative to the record under evaluation in Table A, and then determine if the price in Table A is greater than the price for the most recent matching name in Table B. After that, I need to calculate the difference between the prices. So, in the two records above, the difference would be 2 and 4
Table A
Date | Name | Price
03-08-2019 Bob 6
03-25-2019 Bob 2
03-17-2019 Bob 8
03-20-2019 John 10
Table B
Date | Name | Price
03-16-2019 Bob 4
03-28-2019 Bob 9
03-02-2019 Bob 12
03-10-2019 John 6
Thank you for the help!
Join twice the tables, once to get the min date difference and then to get the row with the min date difference:
select a.*
from tablea a
inner join tableb b on b.name = a.name
inner join (
select a.name, min(abs(datediff(b.date, a.date))) mindatediff
from tablea a inner join tableb b
on b.name = a.name
group by a.name
) g on g.name = a.name and abs(datediff(b.date, a.date)) = g.mindatediff
See the demo.
or:
select a.*
from tablea a inner join tableb b
on b.name = a.name
where abs(datediff(b.date, a.date)) = (
select min(abs(datediff(x.date, y.date)))
from tablea x inner join tableb y
where x.name = a.name and y.name = b.name
)
See the demo.
Results:
| date | name | price |
| ---------- | ---- | ----- |
| 2019-03-17 | Bob | 8 |
| 2019-03-20 | John | 10 |
In MySQL 8+, you would use window functions
select ab.*, (price - b_price)
from (select a.*, b.price as b_price,
row_number() over (partition by a.name order by datediff(b.date, a.date) as seqnum
from a join
b
on a.name = b.name and
a.date >= b.date
) ab
where seqnum = 1;
I have tables A, B and C and I want to get matching values for from all tables (tables have different columns).
Table A (primary key = id)
+------+-------+
| id | name |
+------+-------+
| 1 | Ruby |
| 2 | Java |
| 3 | JRuby |
+------+-------+
Table B (pid is reference to A(id) - No primary key)
+------+------------+
| pid | name |
+------+------------+
| 1 | Table B |
+------+------------+
Table C (primary key = id, pid is reference to A(id))
+------+------+------------+
| id | pid | name |
+------+------+------------+
| 1 | 2 | Table C |
+------+------+------------+
So my below query returned nothing. Whats wrong here? Is it treated as AND when multiple inner joins present?
Select A.* from A
inner join B ON a.id = b.pid
inner join C ON a.id = c.pid;
As you first join
1 | Ruby | Table B
and then try to join Table C, there is no match for pid 2 in the aforementioned result, the result is therefore empty.
An inner join excludes everything that doesn't match. So after you joined against B, you were left with only one record (id=1). Your inner join against C doesn't have any matches from what's left, so you get nothing.
I suppose a union would do the trick:
select A.* from A join B on a.id = b.pid
union
select A.* from A join C on a.id = c.pid
Or there are other ways, like where a.id in (select pid from b) or a.id in (select pid from c)
When you inner-join like this, a single row from A needs to exist such that a.id = b.pid AND a.id = c.pid are true at the same time. If you examine the rows in your examples, you would find that there is a row in A for each individual condition, but no rows satisfy both conditions at once. That is why you get nothing back: the row that satisfies a.id = b.pid does not satisfy a.id = c.pid, and vice versa.
You could use an outer join to produce two results:
select *
from A
left outer join B ON a.id = b.pid
left outer join C ON a.id = c.pid;
a.id a.name b.pid b.name c.id c.pid c.name
1 | Ruby | 1 | Table B | NULL | NULL | NULL
2 | Java | NULL | NULL | 1 | 2 | Table C
Of course you return nothing!
Table A and B inner join returns 1st record of Table A (table A ID = 1)
then you join table C, there is no matching rows to join table C, and vice versa.
I'm new with inner joins and I can't seem how to figure out what is going wrong here. I want all of the rows in the table "events" to be returned. Here are my tables:
+----+---------+----------+ +----+---------+
| ID | name | venue_id | | ID | name |
+----+---------+----------+ +----+---------+
| 1 | Hub dub | 2 | | 2 | hub dub |
| 2 | Test 2 | 2 | +----+---------+
| 3 | Test 3 | 2 |
| 4 | Test 4 | 2 |
+----+---------+----------+
Here is the query:
SELECT DISTINCT a.*, b.name AS venue a
FROM events b
INNER JOIN venues ON a.venue_id = b.id
WHERE a.name LIKE '%hub%' OR b.name LIKE '%hub%'
For some reason, in my more complicated version, only Event ID# 1 is returned.
The syntax is just a bit off. The alias (a) needs to go after the table (you have it after the column alias).
SELECT DISTINCT a.*, b.name AS venue
FROM events b
INNER JOIN venues a ON a.venue_id = b.id
WHERE a.name LIKE '%hub%' OR b.name LIKE '%hub%'
Is it a typo?
SELECT DISTINCT a.*, b.name AS venue a
-------------------------------------^
It should be this way:
SELECT DISTINCT a.*, b.name AS venue
FROM events b
INNER JOIN venues a ON a.venue_id = b.id
WHERE a.name LIKE '%hub%' OR b.name LIKE '%hub%'
It is called as alias. It should be always in the table side, after FROM.
do it like that
SELECT DISTINCT a.*, b.name AS venue
FROM events b
INNER JOIN venues a ON a.venue_id = b.id
WHERE a.name LIKE '%hub%' OR b.name LIKE '%hub%'
Is this what you wanted?
SELECT DISTINCT a.*, b.name AS venue a
FROM events b
LEFT JOIN venues ON a.venue_id = b.id and b.name LIKE '%hub%'
The result is correct, you has join the two tables by venue_id and id, the result is all rows from table venues with column name of table events, after that you filter the column name present on the two tables with string contains %hub%, the result is only first row.
PS You missed the a label for the table venues.
I think what you want is Left Join table A with B.
SELECT a.*, b.name AS venue FROM events b
LEFT JOIN venues a ON a.venue_id = b.id
WHERE a.name LIKE '%hub%' OR b.name LIKE '%hub%'
http://www.sqlfiddle.com/#!2/a2581/1/0