How to join two tables without duplicates? - php

I have an in table that looks like this:
id_in | date_in
-------|--------------------------
1 | 2016-04-29 02:00:00
And an out table that looks like this:
id_out | date_out
----------|--------------------------
1 | 2016-04-29 03:00:00
2 | 2016-04-29 04:00:00
3 | 2016-04-29 05:00:00
I want to write a query whose output looks like this:
id_in | date_in | id_out | date_out
------|---------------------------- |----------------------------|---------------------------
1 | 2016-04-29 02:00:00 | 1 |2016-04-29 03:00:00
NULL | NULL | 2 |2016-04-29 04:00:00
NULL | NULL | 3 |2016-04-29 05:00:00

You can do this with a left join:
select i.id_in, i.date_in, o.id_out, o.date_out
from outtable o left join
intable i
on o.id_in = i.id_out;

Or you can do this with a right join
select i.id_in, i.date_in, o.id_out, o.date_out
from intable i right join
outtable o
on o.id_in = i.id_out;

Let's call the table with id_in 'table_in' and the table with id_out 'table_out'
You want to join table_in to table_out. In this case, you want to left join table_in to table_out on the id field. This will ensure you return all records from table_out regardless of whether they have a corresponding record in table_in:
select table_in.id_in, table_in.date_in, table_out.id_out, table_out.date_out
from table_out
left join table_in
on table_out.id_out = table_in.id_in
(Alternatively, you can table_in right join table out for the same results)
If you want all the records from both tables regardless of whether there is a corresponding record in the other, you should use full join.

simple you can try this
select * from table_id i right join table_out o on i.id_in = o.id_out

This query results the same as your need..
SELECT a.id_in, a.date_in, b.id_out, b.date_out
FROM intable AS a RIGHT JOIN
outtable AS b
ON a.id_in = b.id_out

Related

mysql query for join two table with like

company_name | macid | expiry_date
---------------------------------------------
abc | 123456789012 | 2017-03-23
qwe | 987654321012 | 2018-05-24
asd | 456789123012 | 2019-07-07
abc | 789456123000 | 2017-03-23
abc | 445544444444 | 2018-03-03
abc | 555555555555 | 2017-03-25
company_name | desktop | server
abc 123456789012 555555555555
789456123000
I have above two table and I want all macid and expiry date which is present in table1 and table2. Also I have store all macid as new line and desktop macid and server macid in different columns. My query
"select a.macid,a.expity_date from table1 a,table2 b where a.macid like b.desktop or a.macid like %'b.server%'"
but is show result null. Please help to solved.
I want result
macid | expiry_date
---------------------------------------------
123456789012 | 2017-03-23
789456123000 | 2017-03-23
555555555555 | 2017-03-25
for table2 if I want to search mac_id them I have to use
"select * from table2 where desktop like '%123456789012%'"
I can not retrieve record without %(percentage)
I think it is just a typo, not expity_date, it's expiry_date in your query, see demo.
select a.macid, a.expiry_date
from table1 a, table2 b
where a.macid like b.desktop or a.macid like b.server
However, it is more better to use join not a comma(,) to do join things:
select a.macid, a.expiry_date
from table1 a
join table2 b
on a.macid like b.desktop or a.macid like b.server
also check demo here.
Another thing is if desktop and server is as same as macid, just use equal(=) is fine as well.
You have to make two separate JOIN and then UINON the results.
SELECT macid, expiry_date
FROM table1 JOIN table2
ON table1.macid = table2.desktop
UNION
SELECT macid, expiry_date
FROM table1 JOIN table2
ON table1.macid = table2.server
Here is the working demo: http://sqlfiddle.com/#!9/dccea43/1
Try this:
"select a.macid,a.expity_date from table1 a JOIN table2 b ON (a.macid like b.desktop OR a.macid like b.server)"

Join three table for Report in Mysql

I would like to produce report for airlines using
Date Table
Airline Table
Route Table
My date table include series of date
Entryid | Date
----------------
1 |2016-06-01
2 |2016-06-02
4 |2016-06-03
5 |2016-06-04
6 |2016-06-05
7 |2016-06-06
My airline table include
id|name
---------
1 |Air1
2 |Air2
3 |Air3
and Route table:
id|date |airline|routename
1|2016-06-01|1 |city1-city2
2|2016-06-01|1 |city1-city3
3|2016-06-01|2 |city1-city3
4|2016-06-02|2 |city1-city3
5|2016-06-02|2 |city1-city3
6|2016-06-04|2 |city1-city3
7|2016-06-04|2 |city1-city3
8|2016-06-04|1 |city1-city3
by using these three table I want to produce result as follow"
Date |Airline|totleroute
2016-06-01 | Air1 | 2
2016-06-01 | Air2 | 1
2016-06-02 | Air1 | 0
2016-06-02 | Air2 | 2
2016-06-03 | Air1 | 0
2016-06-03 | Air2 | 0
2016-06-04 | Air1 | 1
2016-06-04 | Air2 | 2
How to produce desired result from joining three tables?
You can use a query like the following:
SELECT d.`date`, t.`name`, COUNT(r.`routename`) AS TotalRoutes
FROM `Date` AS d
CROSS JOIN (
SELECT DISTINCT r.`airline`, a.`name`
FROM Route AS r
INNER JOIN Airline AS a ON r.airline = a.id
) AS t
LEFT JOIN Route AS r ON d.`date` = r.`date` AND t.`airline` = r.`airline`
GROUP BY d.`date`, t.`airline`
The CROSS JOIN is used in order to produce a result for each date - airline combination, as suggested by the sample output in the OP.
Demo here
Please try this query:
select e.date,a.name airline, count(r.id) total_route from route_tbl r
LEFT join entry_tbl e on r.date =e.date
LEFT join airline_tbl a on a.id= r.id
order by r.date
group by r.date
It seems you need a so called FULL JOIN to have all combinations of Date and Route entries with a column containing the number of routes per day and airline.
Regrettably MySQL lacks support for FULL JOIN, there is a feature request open since some years.
It is still possible to emulate such a feature. A good reading would be https://explainextended.com/2009/04/06/emulating-full-outer-join-in-mysql/

Select from 2 tables with 2 foreign keys

I have a question for you and I have not found a solution to this, So I have 2 tables:
dosar
id name date fk_user fk_verificator
1 dosar 1 08/08/14 1 2
users
id name is_admin is_verificator
1 admin Y N
2 verificator N Y
fk_user is foreign key pointed to users, fk_verificator is also a foreign key pointed to users table.So I need to create an select to get 2 users for dosar
name date name is_admin is_verificator
dosar1 08/08/14 admin Y N
verificator N Y
My query:
$uid = (int) $this->uri->segment(3, 0);
$this->load->database();
$get_dosar = $this->db->query("SELECT * FROM dosar,users WHERE
users.id = dosar.fk_user AND
users.id = dosar.fk_verificator
AND dosar.id_dosar = $uid");
Help me please guys.
This uses modern join syntax (it is a good practice not to put join conditions in the WHERE clause):
Fiddle:
http://sqlfiddle.com/#!9/d6e60/2/0
select d.name, d.date, u.is_admin, u.is_verificator
from dosar d
join users u
on u.id = d.fk_user
or u.id = d.fk_verificator
where d.id = $uid
Output (for ID #1 on dosar):
| NAME | DATE | IS_ADMIN | IS_VERIFICATOR |
|---------|-------------------------------|----------|----------------|
| dosar 1 | August, 08 2014 00:00:00+0000 | Y | N |
| dosar 1 | August, 08 2014 00:00:00+0000 | N | Y |
You seem to want to not repeat values of NAME or DATE where it is the same as the previous row. That should be done in PHP, not the SQL.
Because you're always just selecting one ID it's somewhat simple to do it in MySQL as well (see below) however I would still recommend doing that part in PHP.
select case when rn = 1 then name end as name,
case when rn = 1 then date end as date,
is_admin,
is_verificator
from(select d.name, d.date, u.is_admin, u.is_verificator, #rw := #rw + 1 as rn
from dosar d
join users u
on u.id = d.fk_user
or u.id = d.fk_verificator
cross join (select #rw := 0) r
where d.id = 1) x
Output:
| NAME | DATE | IS_ADMIN | IS_VERIFICATOR |
|---------|-------------------------------|----------|----------------|
| dosar 1 | August, 08 2014 00:00:00+0000 | Y | N |
| (null) | (null) | N | Y |
Fiddle:
http://sqlfiddle.com/#!9/d6e60/3/0
Your default JOIN type doesn't work here.
Check
MySQL: Quick breakdown of the types of joins
And probably you need an outer join between the tables.
(And after your change to the question, probably a RIGHT JOIN)
How about that? Please let me know if it doesn't satisfy and why. If it does work then I'll explain why.
"SELECT d.name,d.date,u.name,u.is_admin,u.is_verificator
FROM dosar d,users u WHERE
users.id = dosar.fk_user OR
users.id = dosar.fk_verificator
AND dosar.id_dosar = $uid"
If you really want blank cells, I would suggest avoiding putting that burden on the SQL.

SQL - Selecting using only the first result of the INNER JOIN

I'm trying to get some results from 2 tables, they are 1 to n relations. I want to get 2 columns from one table Extensao and one result from the second table HorarioExtensao. I'm trying to filter by month, but I just want to consider the lower date of the second column, since the same result can have multiple dates from different months.
I already tried to query on HorarioExtensao and then do another SELECT using the MIN(h.hora) BETWEEN $inicial and $final, but the problem is there I don't know where to put the INNER JOIN for Extensao to select e.nome and e.codigo. Thanks in advance.
$mes = $_GET["mes"];
$ano = $_GET["ano"];
$inicial = date("Y/m/d g:i:s",mktime(0,0,0,$mes,1,$ano));
$final = date("Y/m/t g:i:s",mktime(0,0,0,$mes,1,$ano));
$db = pg_connect("host=localhost dbname=saga user=**** password=****");
$result = pg_query($db,"SELECT e.nome, MIN(h.hora), e.codigo
FROM Extensao e
INNER JOIN HorarioExtensao h ON h.idExtensao = e.idExtensao
WHERE h.hora BETWEEN
to_timestamp('$inicial','YYYY/MM/DD HH:MI:SS') AND
to_timestamp('$final','YYYY/MM/DD HH:MI:SS')
GROUP BY 3,1");
EDIT
On tables:
- Extensao
----------------------
| ID | NOME | CODIGO |
|----|------|--------|
| 1 | N1 | 201 |
| 2 | N2 | 223 |
| 3 | N3 | 266 |
----------------------
- HorarioExtensao
---------------------------
| idExtensao | hora |
|------------|------------|
| 1 | 2012-01-21 |
| 1 | 2012-01-22 |
| 1 | 2012-02-15 |
| 1 | 2012-02-16 |
---------------------------
If I try to select month 2, I don't want to get any result, cause the lower date with the same idExtensao is for month 1. If I select month 1, I want to get 1 result only, which should be N1,2012-01-21,201. Also, I know 2012-01-21 is not a TIMESTAMP, I'm just simplifying.
The question leaves room for interpretation, to put it politely.
I think this might be what you are looking for: a LEFT [OUTER ] JOIN on a pre-aggregated table:
SELECT e.nome, h.min_hora, e.codigo
FROM extensao e
LEFT JOIN (
SELECT idextensao, min(hora) AS min_hora
FROM horarioextensao
GROUP BY 1
) h ON h.idextensao = e.id
AND h.min_hora >= to_timestamp($inicial, 'YYYY/MM/DD HH:MI:SS')
AND h.min_hora < to_timestamp($final, 'YYYY/MM/DD HH:MI:SS');
In subquery h, I pick the earliest hora per idextensao from horarioextensao before joining to extensao.
Note also how I pull up WHERE conditions into the LEFT JOIN condition. This way you get all rows from extensao and only those rows from horarioextensao that match the conditions.
Change to a plain JOIN if you only want rows from extensao that have a matching min_hora. Conditions can stay in the WHERE clause in this case.
The result for January in your example would be:
nome | min_hora | codigo
-----+------------+---------
N1 | 2012-01-21 | 201
N2 | null | 223
N3 | null | 266
And for February:
nome | min_hora | codigo
-----+------------+---------
N1 | null | 201
N2 | null | 223
N3 | null | 266
->sqlfiddle
Try this SQL Server syntax - you will need to translate it but it should give your the right idea
SELECT e.nome,MIN(h.hora),e.codigo
FROM Extensao e
CROSS APPLY
(SELECT TOP(1) h.hora
FROM HorarioExtensao h
WHERE h.idExtensao = e.idExtensao
AND
h.hora >= to_timestamp('$inicial','YYYY/MM/DD HH:MI:SS')
AND
h.hora < to_timestamp('$final','YYYY/MM/DD HH:MI:SS')
ORDER BY h.hora)
GROUP BY 3,1

PHP MySQL: How to select multiple tables and return output summary with good performance?

How to get result on PHP:
NU61 - sun - 2011
KE2I - ball - 2000
B8WO - point - 2008
table_first SELECT id, order, date FROM table_first ORDER BY orders DESC
return id, date
id | orders | date
------+---------+------
KE2I | 2 | 2000
B8WO | 5 | 2008
NU61 | 1 | 2011
table_second SELECT key FROM table_second WHERE id=(id from table_first) get key to reach content from table_third
id | key
------+-----------------
KE2I | .b
B8WO | .p
NU61 | .s
table_third SELECT content FROM table_third WHERE id=(key from table_second) return content
id | content
------+-----------------
.b | ball
.p | point
.s | sun
SELECT `table_first`.`id`,
`table_third`.`content`,
`table_first`.`date`
FROM `table_first`
LEFT JOIN `table_second` USING(`id`)
LEFT JOIN `table_third` ON `table_third`.`id`=`table_second`.`key`
Performance will not be a concern as long as you have indices on:
`table_first`.`id`
`table_second`.`id`
`table_second`.`key`
`table_third`.`id`
This query would do the trick:
SELECT t1.id, t3.content, t1.`date`
FROM table_first t1
JOIN table_second t2 ON t1.id = t2.id
JOIN table_third t3 ON t2.`key` = t3.id;

Categories