How to select 2 table with condition and show all data - mysql

How to select 2 table with condition and show all data
store_profile
id + store_name
1 | Accessorize.me
2 | Active IT
3 | Edushop
4 | Gift2Kids
5 | Heavyarm
6 | Bamboo
store_fee
id + store_id + date_end
1 | 1 | 27-6-2013
2 | 2 | 29-8-2013
3 | 3 | 02-6-2013
4 | 4 | 20-4-2013
Below is my previous query
$query = "select sp.id, sp.store_name, sf.id, sf.store_id, sf.date_end from store_profile sp, store_fee sf where sf.store_id=sp.id"
and the result is something like this :
1 | Accessorize.me 27-6-2013
2 | Active IT 29-8-2013
3 | Edushop 02-6-2013
4 | Gift2Kids 20-4-2013
but what i want is show all store name including date_end but if no date_end still can show store name with empty date_end

You want to use an outer join. With an outer join, columns on the joining table do not need to match the conditional columns in the joined table to get results:
SELECT * FROM store_profile sp LEFT JOIN store_fee sf ON (sf.store_id = sp.id)

Use a left join:
select sp.id, sp.store_name, sf.id, sf.store_id, sf.date_end
from store_profile sp left join store_fee sf on sf.store_id=sp.id

The syntax you are using is interpreted as INNER JOIN, which means that stores without a corresponding entry in store_profile won't show up. You want to use LEFT JOIN:
SELECT sp.id, sp.store_name, sf.id, sf.store_id, sf.date_end
FROM store_profile sp
LEFT JOIN store_fee sf
ON sf.store_id=sp.id
LEFT JOIN means that all records in the first table will be returned, even if there's not a match in the second table.

Related

SQL left join: how to return the newest from tableB and grouped by another field

I've been trying for two days, without luck.
I have the following simplified tables in my database:
customers:
| id | name |
| 1 | andrea |
| 2 | marco |
| 3 | giovanni |
access:
| id | name_id | date |
| 1 | 1 | 5000 |
| 2 | 1 | 4000 |
| 3 | 2 | 1500 |
| 4 | 2 | 3000 |
| 5 | 2 | 1000 |
| 6 | 3 | 6000 |
| 7 | 3 | 2000 |
I want to return all the names with their last access date.
At first I tried simply with
SELECT * FROM customers LEFT JOIN access ON customers.id =
access.name_id
But I got 7 rows instead of 3 as expected. So I understood I need to use GROUP BY statemet as the following:
SELECT * FROM customers LEFT JOIN access ON customers.id =
access.name_id GROUP BY customers.id
As far I know, GROUP BY combines using a random row. In fact I got unordered access dates with several tests.
Instead I need to group every customer id with its corresponding latest access! How this can be done?
You have to get the latest date from the access table with a group by on the the name_id, then join this result with the customer table. Here is the query:
select c.id, c.name, a.last_access_date from customers c left join
(select id, name_id, max(access_date) last_access_date from access group by name_id) a
on c.id=a.name_id;
Here is a DEMO on sqlfiddle.
I think this is what you'd like to achieve:
SELECT c.id, c.name, max(a.date) last_access
FROM customers c
LEFT JOIN access a ON c.id = a.name_id
GROUP BY c.id, c.name
The LEFT join will return all entries in table customers regardless if the join criteria (c.id = a.name_id) is satisfied. This means that you might get some NULL entries.
Example:
Simply add a new row in the customers table (id: 4, name: manuela). The output will have 4 rows and the newest row will be (id: 4, last_access: null)
I would do this using a correlated subquery in the ON clause:
SELECT a.*, c.*
FROM customers c LEFT JOIN
access a
ON c.id = a.name_id AND
a.DATE = (SELECT MAX(a2.date) FROM access a2 WHERE a2.name_id = a.name_id);
If this statement is true:
I need to group every customer id with its corresponding latest access! How this can be done?
Then you can simply do:
select a.name_id, max(a2.date)
from access a
group by a.name_id;
You do not need the customers table because:
All customers are in access, so the left join is not necessary.
You need no columns from customers.

mysql help to make a report

i have two table here is table_user and table_feedback like below
table_user
| id | name |
|----|------|
| 1 | john |
| 2 | tony |
| 3 | mona |
table_feedback
| id | rate | user_id | date |
|----|------|---------|----------|
| 1 | 1 | 3 |2015-11-2 |
| 2 | 1 | 2 |2015-11-2 |
| 3 | 1 | 3 |2015-11-1 |
I wanted to show report by date from table_feedback including name and id from table_user and all user will be show if table_feedback didn't contain the user id then this will be return blank data. I have idea about inner join and here is my query. problem is that the query return 2 row only but i need 3 row including table_user id 1 with blank column rate.
Here is my query below.
SELECT
table_user.id,
table_user.name,
table_feedback.rate,
table_feedback.date
FROM table_feedback
INNER JOIN table_user
ON table_user.id = table_feedback.user_id
WHERE table_feedback = '2015-11-2'
expected_result_table
| user_id | name | rate | date |
|-------- |------|------|----------|
| 1 |jony | |2015-11-2 |
| 2 |tony | 1 |2015-11-2 |
| 3 |mona | 1 |2015-11-2 |
The solution to this is an outer join. Anytime you find yourself thinking along the lines of "I need to see all rows from this table, regardless of a match in another table..." you should look to an outer join.
We can use an outer join to select all users, and link them to the feedbackTable in our JOIN clause. This will return null values for any columns in the table that don't match up. Try this:
SELECT u.id, u.name, t.rate, t.dateCol
FROM userTable u
LEFT JOIN feedbackTable t ON t.user_id = u.id AND t.dateCol = '2015-11-02';
Here is an SQL Fiddle example. As a side note, it is good practice not to name date columns date since that is a keyword in MySQL.
Edit based on your expected results:
To make sure the date column appears in each row, you can hardcode it into your select. If you choose to use a variable, you won't have to update the date twice each time, you can just update the declaration:
SET #reportDate = '2015-11-02';
SELECT u.id, u.name, t.rate, #reportDate
FROM userTable u
LEFT JOIN feedbackTable t ON t.user_id = u.id AND t.dateCol = #reportDate;
Here is an updated SQL Fiddle.
My guess is you need to use LEFT JOIN:
SELECT
table_user.id,
table_user.name,
table_feedback.rate,
table_feedback.date
FROM table_user
LEFT JOIN table_feedback
ON table_user.id = table_feedback.user_id
AND table_feedback.date = '2015-11-2'
In order to include user without feedback you need to use LEFT OUTER JOIN
SELECT
table_user.id,
table_user.name,
table_feedback.rate,
'2015-11-2'
FROM table_feedback
LEFT OUTER JOIN table_user
ON table_user.id = table_feedback.user_id
WHERE table_feedback = '2015-11-2'
You need to do three modifications to your query:
Use LEFT JOIN instead of INNER JOIN (to get all the users)
Change the table order (first the table you want to get all rows
from)
As the user 1 (john) does not have any data in the second table, you
cannot limit the rows in WHERE-clause. Do the limitation in JOIN
instead, so it applies only to the rows that are matching the JOIN.
So:
SELECT
table_user.id,
table_user.name,
table_feedback.rate,
table_feedback.date
FROM table_user
LEFT JOIN table_feedback ON table_user.id = table_feedback.user_id and table_feedback.date = '2015-11-02'

Select data from another table if exists, if not display null

I have two tables.
Invoices
ID | Amount
-----------
1 | 123.54
2 | 553.46
3 | 431.34
4 | 321.31
5 | 983.12
Credit Memos
ID | invoice_ID | Amount
------------------------
1 | 3 | 25.50
2 | 95 | 65.69
3 | 51 | 42.50
I want to get a result set like this out of those two tables
ID | Amount | Cr_memo
---------------------
1 | 123.54 |
2 | 553.46 |
3 | 431.34 | 25.50
4 | 321.31 |
5 | 983.12 |
I've been messing with joins and whatnot all morning with no real luck.
Here is the last query I tried, which pulled everything from the Credit Memo table...
SELECT A.ID, A.Amount FROM Invoices AS A
LEFT JOIN Credit_Memos AS B ON A.ID = B.invoice_ID
Any help or pointers are appreciated.
Your query would work fine. Just add Credit_memo.Amount with an alias:
SELECT Inv.ID,Inv.Amount,IFNULL(C.Amount,'') AS Cr_memo
FROM Invoices Inv LEFT JOIN
Credit_Memos C ON Inv.ID=C.invoice_ID
Result:
ID AMOUNT CR_MEMO
1 124
2 553
3 431 25.50
4 321
5 983
See result in SQL FIDDLE.
You almost got the answer Left Outer Join is what you need but you missed to select Cr_memo from Credit_Memos table. Since you don't want to show Null values when there is no Invoices_ID in Credit Memos table use IFNULL to make NULL's as Empty string
SELECT A.ID, A.Amount, IFNULL(B.Cr_memo,'') AS Cr_memo
FROM Invoices AS A
LEFT JOIN Credit_Memos AS B
ON A.ID = B.invoice_ID
The LEFT JOIN keyword returns all rows from the left table (table1), with the matching rows in the right table (table2). The result is NULL in the right side when there is no match.
SELECT A.ID, A.Amount, IFNULL(B.amount,0) AS Cr_memo FROM Invoices AS A
LEFT JOIN Credit_Memos AS B ON A.ID = B.invoice_ID
here is some useful link about left join link and another

Creating multiple joins accessing the same table

I need a way to extract two user names from the same table. I'm able to pull the first name (jim), but I'm having trouble pulling from the second criteria/join.
The two tables:
tbl_users
usr_index | usr_name
1 | bob
2 | mike
3 | jim
tbl_master
mas_openedby | mas_closedby
3 | 1
1 | 3
2 | 2
tbl_master.mas_openedby = 3
tbl_master.mas_closedby = 2
first results should be(opened by): jim
sec. results should be(closed by): mike
select tbl.users.usr_name
...
FROM tbl_master
LEFT JOIN tbl_users ON tbl_users.usr_index = tbl_master.mas_openedby
LEFT JOIN tbl_users ON tbl_users.usr_index = tbl_master.mas_closedby
You need to assign each join a unique alias:
LEFT JOIN tbl_users AS userjoin1 ON userjoin1.usr_index = tbl_master.mas_openedby
LEFT JOIN tbl_users AS userjoin2 ON userjoin2.usr_index = tbl_master.mas_closedby
... then:
SELECT userjoin1.usr_name, userjoin2.usr_name FROM...

How to pull same row from another table by date in mysql

I have two table .
first table
f_id | date |
--------------
1 |2012-1-01
1 |2012-1-02
second table
s_id | f_id | name
-------------------
1 | 1 |rakib
2 | 1 | shohug
i want to view this data
like
f_id| date | s_id | name
--------------------------
1 |2012-1-01 | 1 | rakib
1 |2012-1-01 | 2 | shohug
1 |2012-1-02 | 1 | rakib
1 |2012-1-02 | 2 | shohug
plz help me how to write it in mysql query
select f.f_id, f.`date`, s.s_id, s.`name`
from firsttable f
join secondtable s on f.f_id=s.f_id
order by f.f_id, f.`date`, s.s_id
Do you just mean
SELECT first.f_id, first.date, second.s_id, second.name
FROM first JOIN second ON second.f_id = first.f_id
?
(See http://en.wikipedia.org/wiki/Join_(SQL).)
Seems you want to do FULL OUTER join it includes all rows from both tables. Mysql does't support it directly.
But you can try below:
select * from firsttable as a
left outer join secondtable as o on a.f_id = o.f_id
union all
select * from firsttable as a
right outer join secondtable as o on a.f_id = o.f_id
Also go through this article will help you http://www.xaprb.com/blog/2006/05/26/how-to-write-full-outer-join-in-mysql/