I have this query:
SELECT id,id1,title FROM tablename
LEFT JOIN tablename AS parent
ON tablename .id1 = parent.id
WHERE parent.id is NULL
What I try to achieve is that only rows are shown from which no parent exist.
Table layout and content
id id1(parent) title
1 0 parent
2 1 child1
3 1 child2
4 100 orphan
5 1 child3
6 1 child4
In this example I would query all but leave out the one which has no existing parent row (row 4, the orphan, parent 100 which does not exists in tablename).
This
SELECT child.id,child.id1,child.name
FROM table AS child --alias names, as column names would be ambiguous
LEFT JOIN table AS parent
ON table.id1 = parent.id
WHERE parent.id is NULL -- only no parent!
Shows the orphans. To get all non-orphans
SELECT child.id,child.id1,child.name
FROM table AS child
JOIN table AS parent -- JOIN takes care of getting only the records with parents
ON child.id1 = parent.id
Why does this work this way? LEFT JOIN is for joining tables, where we would like to receive rows of the left hand side table, where the right hand side table does not have a record that fulfills the join criteria. The columns pertaining to the right hand side table would all be NULL in that case. By using a simple JOIN, only those rows are shown from the first table, that have a record in the table on right hand side of the join.
Why did you get wrong result
The column names can get to be ambiguous when joining tables, and always do so when self-joining... You have to distinguish between them, by using alias names.
Ideas to consider
Maintainability. Keep this in mind, even for examples. Name your objects properly: table is not a descriptive name (and is a keyword too), use PERSON instead. For columns, id1 is not a descriptive name - use PARENT_ID instead...
Your query looks correct, except you need table aliases for the columns in the select:
SELECT table.id, table.id1, table.name
FROM table LEFT JOIN
table AS parent
ON table.id1 = parent.id
WHERE parent.id is NULL ;
The problem is that both table and parent have the same columns. The engine doesn't know which you really want without the table alias.
What I try to achieve is that only rows are shown from which no parent exist.
Surely this is the EXACT OPPOSITE of:
Mysql only select row with exisiting parent
The query in your question seems to exactly meet your requirement only rows are shown from which no parent exist
If you want the opposite of this , use an inner join and lose the where clause:
SELECT id,id1,name FROM table
INNER JOIN table AS parent
ON table.id1 = parent.id;
Try the following query:
SELECT id,id1,title
FROM table
WHERE id1 IS NULL OR id1 NOT IN(SELECT id FROM table);
Related
I have created a temp table from recursion (CTE), then left join PARAM_VALUE from another table. My temp table look like this
I have the BOQ_ITEM_FK which points to ID having the PARAM_VALUE. I want to get the PARAM_VALUE from the parent ID and apply it to the child PARAM_VALUE.
What I have tried:
SELECT ID, BRIEF, REFERENCE, PARAM_VALUE
FROM #BOQ_TABLE
WHERE ID IN (SELECT BOQ_ITEM_FK FROM #BOQ_TABLE)
But I only get:
Thanks in advance
In order to get the PARAM_VALUE from another related row in the same table, you'll need to join the table with itself.
When a query includes the same table multiple times you need to assign an alias to each table instance, in order to identify where each column is coming from. I chose the aliases a and b but you are free to choose any alias that makes sense to you.
Your query could look like:
select
a.id,
a.brief,
a.reference,
b.param_value
from #boq_table a
left join #boq_table b on b.id = a.boq_item_fk
Notice that:
The PARAM_VALUE column is coming from the second table instance and, therefore, comes from a different row.
The query uses an outer join (LEFT JOIN) in case the parent row does not exist.
How to choose the records in A that doesn't intersect with B? The records in A and B are already derived from a couple of inner joins. I tried left join, and right and not exists too, it's giving inappropriate results.
SELECT id FROM A_List
MINUS
SELECT id FROM B_List;
In here give your column name instead of id and remember same column name to give both A and B lists. Give your derived (with inner join) A list and B list for A_List and B_List and try this.
I have two child tables naming imported_cables_entry and imported_cables_entry, and a parent table called cables_entry. The two children have foreign keys columns called cables_id pointing the primary key id of cables_entry.
What I want to achieve is, to write a query, which retrieves all the data from parent matching the following conditions :
if imported_cables_entry.cables_id = cables_entry.id
if local_cables_entry.cables_id = cables_entry.id
Both of these conditions works fine, but retrieves 0 results. When they are executed one by one, then I get the proper results.
Retrieve all the data from parent table, where the conditions for child tables meets. When the Unique id of the parent and the cables_id of the children matches with either conditions.
Query
SELECT `cables_entry`.*, `imported_cables_entry`.*, `local_cables_entry`.*
FROM `cables_entry`
JOIN `imported_cables_entry`
ON `imported_cables_entry`.`cables_id` = `cables_entry`.`id`
JOIN `local_cables_entry`
ON `local_cables_entry`.`cables_id` = `cables_entry`.`id`
Assuming columns of childs tables are identical, you could write the following query :
SELECT
ce.*,
COALESCE(ice.column1, lce.column1) AS column1,
COALESCE(ice.column2, lce.column2) AS column2
FROM cables_entry ce
LEFT JOIN imported_cables_entry ice ON ice.cables_id = ce.id
LEFT JOIN local_cables_entry lce ON lce.cables_id = ce.id
If it is possible to have an entry in cables_entry which is not in ice nor lce and if you don't want to display them, you could add a WHERE clause :
WHERE ice.id IS NOT NULL OR lce.id IS NOT NULL
Edit : if your child tables are completely differents and if you don't bother having multiple null column values, you could simply use the following query :
SELECT
ce.*,
ice.*,
lce.*
FROM cables_entry ce
LEFT JOIN imported_cables_entry ice ON ice.cables_id = ce.id
LEFT JOIN local_cables_entry lce ON lce.cables_id = ce.id
I have two MySQL tables. One is called match_rail and match_complete.
When a bill_number from match_rail is actioned, the record moves to the match_complete table and should no longer be displayed in the match_rail table.
The match_rail table is refreshed hourly. Therefore I need to make sure not to display the same bill_number if it already exists in the match_complete table.
Here is the query:
SELECT
mr.RAMP
mr.ETA
mr.BILL_NUMBER
// few more columns
FROM
matchback_rail mr
JOIN
matchback_complete mc ON mr.BILL_NUMBER = mc.BILL_NUMBER
The above query gives me 0 records. It should give me all records except the ones that exist in both tables.
Not sure if I should be using a JOIN or LEFT JOIN.
Try this query:
SELECT
mr.RAMP
mr.ETA
mr.BILL_NUMBER
// few more columns
FROM
matchback_rail mr
WHERE NOT EXISTS(SELECT 1 FROM matchback_complete
WHERE BILL_NUMBER = mr.BILL_NUMBER)
You want to use a LEFT JOIN, this gives all records in mr, even if there is nothing joined. Then use WHERE to filter out the ones you don't want.
SELECT
mr.RAMP
mr.ETA
mr.BILL_NUMBER
// few more columns
FROM
matchback_rail mr
LEFT JOIN
matchback_complete mc ON mr.BILL_NUMBER = mc.BILL_NUMBER
WHERE mc.BILL_NUMBER IS NULL
How to join two tables and get specific records only?
I have two tables
Supplier -- Columns (supp_id,supp_code,supp_name,address)
SelectedSuppliers -- columns (supplier_id,is_selected, date_a)
I load the all the suppliers to grid view and select specific suppliers by check box
For specific date from supplier table then it goes to SelectedSupplier table .
When I load saved suppliers from SelectedSupplier table I need to view all the suppliers from two tables. Which means if I added a new supplier it should be display when I'm loading second time .
This is my query
SELECT
`supplier`.`supp_id`,
`supplier`.`supp_name`,
`supplier`.`address`,
`supplier`.`supp_code`,
`SelectedSuppliers `.`is_selected`
FROM
`SelectedSuppliers `
LEFT JOIN
`supplier` ON (`shop_list`.`supplier_id` = `supplier`.`supp_id`)
WHERE
SelectedSuppliers.date_a = '2013-1-5'
It works but load SelectedSupplier records only not all records
Thanks.
SELECT
`supplier`.`supp_id`,
`supplier`.`supp_name`,
`supplier`.`address`,
`supplier`.`supp_code`,
`SelectedSuppliers `.`is_selected`
FROM 'supplier',`SelectedSuppliers`
LEFT JOIN `supplier`
ON (`shop_list`.`supplier_id` = `supplier`.`supp_id`)
where SelectedSuppliers.date_a = '2013-1-5'
Please have a look at the image
Just reverse the join order and move the condition into the ON clause to allow the left join to still work:
SELECT
`supplier`.`supp_id`,
`supplier`.`supp_name`,
`supplier`.`address`,
`supplier`.`supp_code`,
`SelectedSuppliers `.`is_selected`
FROM `supplier`
LEFT JOIN `SelectedSuppliers `
ON `shop_list`.`supplier_id` = `supplier`.`supp_id`
AND SelectedSuppliers.date_a = '2013-1-5'
By selecting from suppliers first, then left joining you'll get every supplier row.
Note: It is commonly (and incorrectly) believed that the ON clause may only have "key related" conditions, but in fact it may contain any condition (even one not related to the tables being joined!)
It's not at all clear why you have a reference to shop_list, when that table or alias doesn't appear in your query, or why one of your table names includes a trailing space,
From your description, I think you want supplier to be on the left side of the LEFT JOIN (to return all rows from the supplier table.
(I replaced the reference to shop_list with a reference to the SelectedSuppliers. I left the trailing space on the table name, as in your example query.)
SELECT s.supp_id
, s.supp_name
, s.address
, s.supp_code
, e.is_selected
FROM `supplier` s
LEFT
JOIN `SelectedSuppliers ` e
ON e.supplier_id = s.supp_id
AND e.date_a = '2013-1-5'
All rows will be returned from the table on the left side (in this query, that's supplier), along with any matching rows from the table on the right side.
The value for is_selected in will be NULL when there is no matching row in the SelectedSuppliers table. This can easily be replaced with a 0, if that's desired, by wrapping that in an IFNULL function.
If your intent is to EXCLUDE suppliers that are already selected, we can add a simple predicate to the query to eliminate the matching rows:
WHERE e.supplier_id IS NULL
That will return rows from supplier where there is no matching row in the SelectedSuppliers table,
Use this form
SELECT A1,A2,...
FROM TABLE1,TABLE2,TABLE3,....
WHERE ......
Note: From table names creates a cartesian product of all the values out of which you choose by specifying the where clause.
whatever information you are putting into is_selected column to know whether that information has been supplied or not use that in your where condition. Suppose by default it is 0 (if that is not selected) and you want those records to be loaded then simply put where SelectedSuppliers.is_selected = 0