I have 2 tables:
1:
id | name
1 | test
2 | test1
2.
id | related_id | additional
1 | 1 | 1
2 | 1 | 2
id in 1 table relates with related_id in 2
How to JOIN 1 table with 2 without replication records, so the result will be only 1 row from second table (related_id and additional can be any)
id | name | related_id | additional
1 | test | 1 | 1
2 | test1| NULL | NULL
Update
IF I try to group after INNER/LEFT JOIN, the result is
id | name | related_id | additional
1 | test | 1 | 1
You can group the result with the primary key
select *
from table1 left join table2
on table1.id = table2.related_id
group by table1.id
You can use a join
SELECT
*
FROM table1 as t1
LEFT JOIN (
SELECT
MAX(id),
related_id
FROM table2
) as t2
ON t1.id = t2.related_id
Related
I have made a query like that to get result by joining 3 tables
QUERY 1
SELECT a.user_id, a.nick_id, count(b.invoice_id) AS INVOICES, sum(b.purchase_amount) AS PURCHASES, c.sponsor_id, c.user_first_name, c.user_last_name
FROM table1 a
INNER JOIN table2 b ON a.user_id = b.user_id
INNER JOIN table3 c ON a.user_id = c.user_id
WHERE b.purchase_date BETWEEN '2018-09-01 00:00:00' AND now() and a.user_id IS NOT NULL GROUP BY a.user_id ORDER BY PURCHASES DESC
Table1 (Example)
user_id | nick_id
1 | AGENT1
2 | AGENT2
3 | AGENT3
Table2 (Example)
user_id | invoice_id | purchase_amount | purchase_date
1 | IN001 | 500 | 2018-09-01 14:58:33
2 | IN002 | 1000 | 2018-09-18 22:46:12
Table3 (Example)
user_id | sponsor_id | user_first_name | user_last_name
2 | 1 | John | Doe
3 | 1 | Harry | Wilson
4 | 2 | Peter | Bennington
5 | 2 | Daisy | Cooper
Now on the result of [QUERY 1], I want to perform [QUERY 2]
QUERY 2
SELECT sponsor_id, user_id, user_first_name, user_last_name
FROM
(SELECT * FROM table3 ORDER BY sponsor_id, user_id) table3,
(SELECT #pv := '1') initialisation WHERE find_in_set(sponsor_id, #pv) > 0
AND #pv := concat(#pv, ',', user_id)
After that I will get my desired result. But I want to perform both queries at once in a single query.
Given an example of table:
id | item_id | user_id | bid_price
----------------------------------
The task is to select rows with minimum bid_price for each item_id in the provided set.
For example: item_id = [1, 2, 3] - so I need to select up to three (3) rows, having a minimum bid_price.
Example of data:
id | item_id | user_id | bid_price
----------------------------------
1 | 1 | 11 | 1
2 | 1 | 12 | 2
3 | 1 | 13 | 3
4 | 1 | 14 | 1
5 | 1 | 15 | 4
6 | 2 | 16 | 2
7 | 2 | 17 | 1
8 | 3 | 18 | 2
9 | 3 | 19 | 3
10 | 3 | 18 | 2
Expected result:
id | item_id | user_id | bid_price
----------------------------------
1 | 1 | 11 | 1
7 | 2 | 17 | 1
8 | 3 | 18 | 2
Actually, I'm using Symfony/Docine DQL, but it will be enough with a plain SQL example.
For the all the columns in the rows you could use a inner join on subselect for min bid price
select m.id, m.item_id, m.user_id, m.bid_price
from my_table m
inner join (
select item_id, min(id) min_id, min(bid_price) min_price
from my_table
where item_id IN (1,2,3)
group by item_id
) t on t.item_id = m.item_id
and t.min_price= m.bid_price
and t.min_id = m.id
or .. if you have some float data type you could use a acst for unsigned
select m.id, m.item_id, m.user_id, cast(m.bid_price as UNSIGNED)
from my_table m
inner join (
select item_id, min(id) min_id, min(bid_price) min_price
from my_table
where item_id IN (1,2,3)
group by item_id
) t on t.item_id = m.item_id
and t.min_price= m.bid_price
and t.min_id = m.id
You can use MIN() with GROUP BY in the query:
SELECT id, item_id, MIN(bid_price) AS min_bid, user_id
FROM your_tbl
GROUP BY item_id
HAVING item_id in(1, 2, 3);
Use this query:
SELECT id, item_id, user_id, min(bid_price) as bid_price
FROM YOUR_TABLE_NAME
GROUP BY item_id;
I want to SELECT the all rows from meeting table even its null. My table structure:
attandance table:
id | meeting_id | person_id | time
1 | 1 | 12 | 02:02
2 | 1 | 15 | 02:05
3 | 1 | 22 | 02:05
4 | 2 | 1 | 02:20
5 | 2 | 12 | 02:01
6 | 3 | 12 | 02:03
and meeting table:
id | date
1 | 15-12-2014
2 | 17-12-2014
3 | 19-12-2014
4 | 21-12-2014
The output should be:
If I SELECT the person_id 12 then it should return:
date |time
15-12-2014 | 02:02
17-12-2014 | 02:01
19-12-2014 | 02:03
21-12-2014 | NULL
If I SELECT the person_id 1 then it should return:
date |time
15-12-2014 | NULL
17-12-2014 | 02:20
19-12-2014 | NULL
21-12-2014 | NULL
It is a pretty straightforward outer join between the tables:
select
m.id,
m.date
a.time,
c.someColumn
from
meetings m
left outer join attendance a
on m.id=a.meeting_id
and a.person_id=:person
left outer join someTable c
on m.id=c.id
I have written a more detailed answer on these sorts of joins in the question and answer: How can an SQL query return data from multiple tables
Edit: As per the comment by Andrew, the clause for the personID is in the join rather than in a normal where clause because it is an outer join. If the condition was put into the where clause as normal, it would in fact negate the outer join completely.
I have table structure like below:
id |parent|name |value
1 | 0 | aaa |
2 | 0 | bbb |
3 | 0 | ccc |
4 | 1 | | 111
5 | 1 | | 222
6 | 3 | | 333
I want to display parent if it has child records.
Like:
(parent id + name + value first child)
1 - aaa - 111
3 - ccc - 333
There is no meaning of the first child in the database, you can get the first child by the mininum of the id or the minimum of the value, but the values are not stored with a specific order in the table, so you can't tell which value is the first one.
But, assuming that the id is auto incremental column, then value of the first child is the value of the minimum id, then you can do this:
SELECT
t1.parent,
t2.name,
t1.value
FROM tablename AS t1
INNER JOIN
(
SELECT MIN(id) AS id, parent
FROM tablename
GROUP BY parent
) AS t22 ON t22.id = t1.id AND t1.parent = t22.parent
INNER JOIN tablename AS t2 ON t1.parent = t2.id;
See it in action here:
SQL Fiddle Demo
This will give you :
| PARENT | NAME | VALUE |
-------------------------
| 1 | aaa | 111 |
| 3 | ccc | 333 |
Or: You can get it by the minimum value:
SELECT
t1.parent,
t2.name,
MIN(t1.value) AS value
FROM tablename AS t1
INNER JOIN tablename AS t2 ON t1.parent = t2.id
GROUP BY t1.parent, t2.name;
See it in action:
SQL Fiddle Demo
This will give you:
| PARENT | NAME | VALUE |
-------------------------
| 1 | aaa | 111 |
| 3 | ccc | 333 |
I have two tables with a single common field.
Here is how these two table structures are
Table 1
+--ID--+--Title----+----others---+
| 123 | Title 1 | other values|
| 124 | Title 2 | other values|
| 125 | Title 3 | other values|
| 126 | Title 4 | other values|
+------+-----------+-------------+
Table 2
+--ID--+--Tag ID--+----others---+
| 123 | 11 | other values|
| 123 | 12 | other values|
| 123 | 13 | other values|
| 123 | 14 | other values|
| 124 | 15 | other values|
| 124 | 16 | other values|
| 125 | 17 | other values|
| 126 | 18 | other values|
+------+----------+-------------+
I want to show that Article ID 123 have 4 tags i.e 11,12,13 & 14 like the table below
+--Article ID--+--Article Title--+--Tags--+--Tag IDs------+
| 123 | Title 1 | 4 | 11, 12, 13, 14|
| 124 | Title 2 | 2 | 15, 16 |
| 125 | Title 3 | 1 | 17 |
| 126 | Title 4 | 1 | 18 |
+--------------+-----------------+--------+---------------+
I'm very new to PHP and MySQL and trying to learn it.
Someone please help me to know how I can get the desired result.
This query should work (with some tweaking).
SELECT `ID` AS `t1`.`Article ID`, `t2`.`Title` AS `Article Title`, COUNT(`t2`.`ID`) AS `Tags`,
GROUP_CONCAT(`t2`.`ID`) AS `Tag IDs` FROM `Articles` AS `t1`
LEFT JOIN `Tags` AS `t2` ON `t1`.`ID` = `t2`.`ID`
GROUP BY `t1`.`ID`
There's a couple of other options to the GROUP_CONCAT function, but the defaults should work fine for what you want.
SELECT t1.id AS 'Article ID',
t1.title AS 'Article Title',
count( t2.tag_id ) AS 'Tags',
GROUP_CONCAT( t2.Tag_Id order by t2.Tag_id ASC) AS `Tag IDs`
FROM table1 t1
JOIN table2 t2 ON ( t1.id = t2.id )
GROUP BY t1.id;
Hope this works!
As somebody already mentioned in the comments, you should use GROUP_CONCAT(). Here are some examples and options - http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat
SELECT table1.*,
table2.tagidgroup
FROM table1
INNER JOIN (SELECT id,
Group_concat(tagid SEPARATOR ',' ) AS tagidgroup
FROM table2
GROUP BY id) Table2
ON table1.id = Table2.id
Merging tables is done by using JOIN (LEFT, RIGHT INNER) keyword. For example:
SELECT T1.*, T2.*, COUNT(T2.ID) AS TAG_COUNT, GROUP_CONCAT(T2.ID) AS TAG_IDS
FROM TABLE1 T1
LEFT OUTER JOIN TABLE2 T2
ON T1.TAG_ID = T2.ID
This type of joining structure suggest, that you have a common filed, by which the join itself is made.
In your table structure I assume, that first table T1 is Article's table, second one is Tags table. In this case you need to have a field in your T1 table, which corresponds to the field in T2, this is most probably ID.
Edit: As final step you need to concatenate the results in order to achieve the desired structure, as many of the answers said - use GROUP_CONCAT() function.