Combine records from two tables in one query - mysql

I have the following tables,
select * from tbl1;
+------+------------+---------+----------+
| id | userId | part_id | url |
+------+------------+---------+----------+
| 1 | 155 | 1 | "http:/" |
+------+------------+---------+----------+
select * from tbl2;
+------+------------+---------+-------------+------------+-----------+
| id | userId | part_id | tbl2_id1 | tbl2_id2 | notes |
+------+------------+---------+-------------+------------+-----------+
| 1 | 155 | 1 | 12 | 1 | note 1 |
| 2 | 155 | 1 | 12 | 2 | note 2 |
+------+------------+---------+-------------+------------+-----------+
As you can see tbl2 has two FK (userId and part_id), tbl2_id1 and tbl2_id2 are the PK of tbl2.
My question is how can I get the three records from both tables in one query?
Something like this
1 | 155 | 1 |"http:/" | from tbl1
1 | 155 | 1 | note 1 | from tbl2
2 | 155 | 1 | note 2 | from tbl2

You want to use union all:
select id, userId, part_id, url, 'from tbl1' as which
from tbl1
union all
select id, userId, part_id, notes, 'from tbl2'
from tbl2;

Related

Joining multiple rows with same ID in one

I am having trouble with an SQL query. I have two tables.
My first table:
+------------+-------------+---------------+
| id_mission | Some column | Other column |
+------------+-------------+---------------+
| 1 | ... | ... |
| 2 | ... | ... |
+------------+-------------+---------------+
My second table:
+------------+-------------+---------+
| id_mission | id_category | points |
+------------+-------------+---------+
| 1 | 1 | 3 |
| 1 | 2 | 4 |
| 1 | 3 | 4 |
| 1 | 4 | 8 |
| 2 | 1 | -4 |
| 2 | 2 | 3 |
| 2 | 3 | 1 |
| 2 | 4 | -7 |
+------------+-------------+---------+
And I would like to have this kind of result with my SELECT request
+------------+-------------+--------------+---------------+----------------+
| id_mission | Some column | Other column | id_category 1 | id_category X |
+------------+-------------+--------------+---------------+----------------+
| 1 | ... | ... | ... | ... |
| 2 | ... | ... | ... | ... |
+------------+-------------+--------------+---------------+----------------+
I have tried this with the first two column but it doesn't work, I also tried GROUP_CONCAT, it works but it's not the result I want.
SELECT m.id_mission ,mc.id_category 1,mc1.id_category 2
from mission m
left join mission_category mc on m.id_mission = mc.id_mission
left join mission_category mc1 on m.id_mission = mc1.id_mission
Can someone help me?
You can use conditional aggregation. Assuming that you want to pivot the points value per category:
select
t1.*,
max(case when t2.id_category = 1 then points end) category_1,
max(case when t2.id_category = 2 then points end) category_2,
max(case when t2.id_category = 3 then points end) category_3
from t1
inner join t2 on t2.id_mission = t1.id_mission
group by t1.id_mission
This assumes that id_mission is the primary key of t1 (else, you need to enumerate the columns you want in both the select and group by clauses).

SQL: How to aggregate multiple rows according to commutable columns?

Table MESSAGES (example of log messages from one user to the other):
| id | from_user_id | to_user_id | message_body |
| 1 | 7 | 10 | ... |
| 2 | 3 | 1 | ... |
| 3 | 95 | 14 | ... |
| 4 | 95 | 3 | ... |
| 5 | 1 | 3 | ... |
| 6 | 1 | 3 | ... |
| 7 | 10 | 7 | ... |
| 8 | 3 | 95 | ... |
...
I would like to COUNT (or execute any other aggregate function) how many users' conversation I have in this table.
A conversation is defined as a message from A to B OR from B to A. Notice that the order doesn't count as the ids are commutable one to each other.
So, the result I would like to get is:
Table CONVERSATIONS:
| id | user_id_1 | user_id_2 | messages_count |
| 1 | 7 | 10 | 2 |
| 2 | 3 | 1 | 3 |
| 3 | 95 | 14 | 1 |
| 4 | 95 | 3 | 2 |
...
How would I be able to do this using a SQL Query?
One option is to use least and greatest:
select least(from_user_id, to_user_id) user_id_1,
greatest(from_user_id, to_user_id) user_id_2,
count(*)
from messages
group by 1, 2
SQL Fiddle Demo
SELECT user1,
user2,
COUNT(*) as messageCount
FROM
(
SELECT from_user_id as user1,
to_user_id as user2
FROM T
WHERE from_user_id<= to_user_id
UNION ALL
SELECT to_user_id as user1,
from_user_id as user2
FROM T
WHERE from_user_id> to_user_id
) as T1
GROUP BY user1,user2
SQLfiddle demo

Mysql count column values and merge columns

I was having problems in creating counting rows by grouping based on a given field value.
For example: I have a Table A structure like this:
+------+------------+
| id | Person |
+------+------------+
| 1 | "Sandy" |
| 2 | "Piper" |
| 3 | "Candy" |
| 4 | "Pendy" |
+------------+------+
Also I have a Table B structure like this:
+------+------------+---------+
| id | Person | Point |
+------+------------+---------+
| 1 | "Sandy" | 10 |
| 2 | "Piper" | 20 |
| 3 | "Candy" | 30 |
| 4 | "Sandy" | 10 |
| 5 | "Piper" | 20 |
| 6 | "Zafar" | 30 |
+------------+------+---------+
And needed a result like:
+------+------------+---------+
| id | Person | Point |
+------+------------+---------+
| 1 | "Piper" | 40 |
| 2 | "Candy" | 30 |
| 3 | "Zafar" | 30 |
| 4 | "Sandy" | 20 |
| 5 | "Pendy" | 0 |
+------------+------+---------+
I hope the table examples are itself self-explanatory.
SELECT person
, SUM(point) total
FROM
( SELECT person,point FROM table_b
UNION
ALL
SELECT person,0 FROM table_a
) x
GROUP
BY person
ORDER
BY total DESC;
It is a simple left join with a group by
select tableA.person, sum(tableB.points) from tableA left join tableB on tableA.person = tableB.person group by tableA.person
union
select tableB.person, sum(tableB.points) from tableB left join tableA on tableA.person = tableB.person where tableA.id is null group by tableA.person
I think below sql useful to you.
select a.id, a.Person,b.total_point from (
select id, Person from tablea) as a join
(select Person, sum(Point) as total_point from tableb group by person) as b on a.person =b.person
Thank you

select a column of data then a count of that column's value when a certain condition is true

Let's say I have a table like this:
project_id | created_by | created
1 | 3 | 2015-04-01
2 | 3 | 2015-04-07
3 | 4 | 2015-05-01
4 | 4 | 2015-05-02
and I want to select these columns, then a count of how many projects were created by the created_by before each project, to look like this:
project_id | created_by | created | previous by created_by user
1 | 3 | 2015-04-01 | 0
2 | 3 | 2015-04-07 | 1
3 | 4 | 2015-05-01 | 0
4 | 4 | 2015-05-02 | 1
How do I select the count for that last column? I've tried count(case where [condition] then 1 else null end) but I keep only getting one row of results when I use that.
You can use a subquery which i already mentioned in the comments.
For Example the query could look like this:
SELECT t1.*,
(SELECT count(*)
FROM Table t2
WHERE UNIX_TIMESTAMP(t2.date) < UNIX_TIMESTAMP( t1.date)
AND t2.created_by = t1.created_by) before
FROM Table t1
It will return the columns of the the Table 'Table' and the result of the subquery as column 'before' which contains the count of before created rows.
Is this what you are after ?
select
project_id,
created_by,
created,
rn as `previous by created_by user`
from(
select
project_id,
created_by,
created,
#rn:=if(#prev_created_by = created_by,#rn+1,0) as rn,
#prev_created_by := created_by
from project,(select #rn:=0,#prev_created_by:=null)x
order by created_by,created
)x;
Here is a test case
mysql> select * from project ;
+------------+------------+------------+
| project_id | created_by | created |
+------------+------------+------------+
| 1 | 3 | 2015-04-01 |
| 2 | 3 | 2015-04-07 |
| 3 | 4 | 2015-05-01 |
| 4 | 4 | 2015-05-02 |
+------------+------------+------------+
4 rows in set (0.00 sec)
The above query will have
+------------+------------+------------+-----------------------------+
| project_id | created_by | created | previous by created_by user |
+------------+------------+------------+-----------------------------+
| 1 | 3 | 2015-04-01 | 0 |
| 2 | 3 | 2015-04-07 | 1 |
| 3 | 4 | 2015-05-01 | 0 |
| 4 | 4 | 2015-05-02 | 1 |
+------------+------------+------------+-----------------------------+
Select t1.project_id , t1.created_by, t1.created,count(t2.created)
from t1 , (select created_by,created from t1) as t2
Where t1.created_by=t2.created_by and t1.created>t2.created
group by t1.project_id ,t1.created_by, t1.created

How to fetch data from two tables using mysql query with some conditions applied to the second table?

I want to generate a result from a MySql query with below requirement.
Table 1 :
---------------
| nid | type |
---------------
| 1 | forum |
| 2 | forum |
| 3 | forum |
| 4 | forum |
---------------
Table 2
-----------------------
| nid | cid | created |
-----------------------
| 1 | 32 | 123456 |
| 2 | 65 | 123457 |
| 4 | 67 | 123458 |
| 1 | 61 | 123491 |
| 1 | 78 | 123497 |
| 2 | 23 | 123498 |
| 1 | 12 | 123698 |
| 4 | 54 | 132365 |
| 4 | 81 | 135698 |
| 1 | 30 | 168965 |
-----------------------
Now i require result like below. (Condition : I need the nid from first table, smallest cid for the corresponding nid in second table WHERE type = 'forum')
--------------
| nid | cid |
--------------
| 1 | 12 |
| 2 | 23 |
| 4 | 67 |
--------------
You can try this
SELECT tbl1.nid,
min(tbl2.cid) as cid
FROM table1 tbl1
INNER JOIN table2 tbl2 ON tbl1.nid=tbl2.nid
GROUP BY tbl2.nid;
SQL Fiddle
Try this
SELECT t1.nid,
min(t2.cid) as cid
FROM table1 t1
INNER JOIN table2 t2 ON t1.nid=t2.nid
GROUP BY t2.nid;
This could also work
select nid, min(cid) cid
from table2
group by nid
The above queries are have issues in group by clause. Kindly check this query.
SELECT t1.NID, MIN(t2.CID) AS cis from
TAB1 t1 inner join TAB2 t2 on t1.nid = t2.nid
group by t1.nid