SQL Left Outer Join Affecting Sub Query Order - mysql

I have a query that contains a sub-query and many Left Outer Joins. Within my sub-query, I am ordering by records by the most recent blog_date and limiting the results by 10 records. This sub-query should dictate the order of the records with the other joins matching up additional information about that record, however, when I add in the LEFT OUTER JOIN it disregards the blog_date ordering. This has led me to believe that I am either missing a key element to persisting the ordering or that LEFT OUTER JOIN is not the right join to be using.
Here is my full query:
SELECT `b`.`blog_id`, `b`.`blog_date`,`b`.`title`, `u`.`user_id`, `u`.`first_name`, `c`.`category_name`, `d`.`discovery_source_name`, `bc`.`comment`, `bf`.`file`
FROM (SELECT * FROM `blog` ORDER BY `blog`.`blog_date` DESC limit 10) `b`
LEFT OUTER JOIN `user` `u` ON `b`.`user_id` = `u`.`user_id` AND `u`.`organization_id` = 1
LEFT OUTER JOIN `category` `c` ON `b`.`category_id` = `c`.`category_id`
LEFT OUTER JOIN `discovery_source` `d` ON `b`.`discovery_source_id` = `d`.`discovery_source_id`
LEFT OUTER JOIN `blog_comment` `bc` ON `b`.`blog_id` = `bc`.`blog_id`
LEFT OUTER JOIN `blog_file` `bf` ON `b`.`blog_id` = `bf`.`blog_id`
;
Here are the results when I just include the first join (user) the records are in the correct order (2017-02-21 most recent):
However, when I add in the second left outer join (and remaining) it appears that the new order is in descending blog_date order, but then grouped by category_name.

Ordering the subquery has no effect on the order of your outer query. Put the ORDER BY at the end of the outer query.
SELECT `b`.`blog_id`, `b`.`blog_date`,`b`.`title`, `u`.`user_id`, `u`.`first_name`, `c`.`category_name`, `d`.`discovery_source_name`, `bc`.`comment`, `bf`.`file`
FROM (SELECT * FROM `blog` ORDER BY `blog`.`blog_date` DESC limit 10) `b`
LEFT OUTER JOIN `user` `u` ON `b`.`user_id` = `u`.`user_id` AND `u`.`organization_id` = 1
LEFT OUTER JOIN `category` `c` ON `b`.`category_id` = `c`.`category_id`
LEFT OUTER JOIN `discovery_source` `d` ON `b`.`discovery_source_id` = `d`.`discovery_source_id`
LEFT OUTER JOIN `blog_comment` `bc` ON `b`.`blog_id` = `bc`.`blog_id`
LEFT OUTER JOIN `blog_file` `bf` ON `b`.`blog_id` = `bf`.`blog_id`
ORDER BY `b`.`blog_date` DESC ;

Related

duplicate datas coming in codeigniter left join

SELECT *
FROM `tbl_schedule_task` AS `E`
JOIN `tbl_schedule` AS `S` ON `S`.`schedule_id`=`E`.`schedule_id`
JOIN `tbl_schedule_frequency` AS `F` ON `F`.`frequency_id`=`S`.`frequency_id`
JOIN `tbl_equipments` AS `M` ON `M`.`equipment_id`=`E`.`equipment_id`
LEFT JOIN `tbl_schedule_checklist` AS `L` ON `L`.`check_list_id`=`E`.`check_list_id`
LEFT JOIN `tbl_tech_groups` AS `G` ON `G`.`group_id` = `S`.`shedule_assign_id`
LEFT JOIN `tbl_tech_technicians` AS `T` ON `T`.`techgroup_id`=`G`.`group_id`
LEFT JOIN `tbl_schedule_category` AS `SC` ON `SC`.`category_id`=`S`.`category_id`
JOIN `tbl_site_users` AS `U` ON `U`.`user_id`=`E`.`created_by`
WHERE `E`.`site_id` = '1'
AND (`E`.`approve_flg` =0
AND `E`.`check_out` = 1)
AND `E`.`approve_by` = '2'
ORDER BY `E`.`task_id` DESC
May be inner joins is returning the duplicate data. Check the inner joins before left joins of above query.

SQL: Unknown column 'items.id' Relationship Query

I have issues with this query. I think the issue is with not finding the items. Afterwards I am doing LEFT OUTER JOIN on it but before that nothing. What is the best solution to include the items table in the beginning ?
SELECT COUNT(*) AS `numrows` FROM (`categories_items`)
LEFT OUTER JOIN `items_stones` `items_stones` ON `items`.`id` = `items_stones`.`item_model_id`
LEFT OUTER JOIN `items` ON `items`.`id` = `categories_items`.`item_model_id`
WHERE ( `items_stones`.`stone_model_id` = 1 ) AND `categories_items`.`category_model_id` = 1
Change your query to be like below, basically swap the LEFT JOINS
SELECT COUNT(*) AS `numrows`
FROM `categories_items`
LEFT OUTER JOIN `items` ON `items`.`id` = `categories_items`.`item_model_id`
AND `categories_items`.`category_model_id` = 1
LEFT OUTER JOIN `items_stones` ON `items`.`id` = `items_stones`.`item_model_id`
AND `items_stones`.`stone_model_id` = 1;

Select MySQL Month() for null column

Got a question to ask. How do i get to list all of my left table to display the data when i use the left join even when some row got null value in it?
Heres my query:
SELECT *, SUM(transactions.debit_credit) current_spending
FROM (`budget`) LEFT JOIN `categories` ON `budget`.`category`=`categories`.`idcategory`
LEFT JOIN `user_category` ON `budget`.`category`=`user_category`.`idcategory`
LEFT JOIN `category_transaction` ON `budget`.`category`=`category_transaction`.`idcategory`
LEFT JOIN `transactions` ON `category_transaction`.`idtransaction`=`transactions`.`idtransaction`
WHERE `user_category`.`iduser` = '1'
AND MONTH(transactions.transaction_date) = '11'
GROUP BY `budget`.`idbudget`;
When I remove AND MONTH(transactions.transaction_date) = '11' the query works fine accept it displays all data instead of just 1 month of transaction.
Help?? Please?? Any idea how??
Your where clause turns your left join into an inner join because you filter the data on a condition of a joined table.
Instead put that condition in the on clause of your join
SELECT *, SUM(transactions.debit_credit) current_spending
FROM (`budget`)
LEFT JOIN `categories` ON `budget`.`category`=`categories`.`idcategory`
LEFT JOIN `user_category` ON `budget`.`category`=`user_category`.`idcategory`
AND `user_category`.`iduser` = '1'
LEFT JOIN `category_transaction` ON `budget`.`category`=`category_transaction`.`idcategory`
LEFT JOIN `transactions` ON `category_transaction`.`idtransaction`=`transactions`.`idtransaction`
AND MONTH(transactions.transaction_date) = '11'
GROUP BY `budget`.`idbudget`;

Unknown column in 'where clause'. Neste subquery to improve perfomance of 'ORDER BY'

I have an a relationship a little odd but must be so:
SELECT COUNT(DISTINCT `t`.`id`)
FROM `radcliente` `t`
LEFT OUTER JOIN `radcliente_endereco_instalacao` `endereco_instalacao`
ON (`endereco_instalacao`.`cliente_id`=`t`.`id`)
LEFT OUTER JOIN `radcliente_telefone` `telefones`
ON (`telefones`.`cliente_id`=`t`.`id`)
LEFT OUTER JOIN `radcliente_email` `emails`
ON (`emails`.`cliente_id`=`t`.`id`)
LEFT OUTER JOIN `radmetodo_cobranca` `metodo_cobranca`
ON (`metodo_cobranca`.`cliente_id`=`t`.`id`) AND (metodo_cobranca.arquivo = 'nao')
LEFT OUTER JOIN `radacct` `ultimo_acct`
ON (`ultimo_acct`.`username`=`t`.`login`)
AND (ultimo_acct.radacctid = (
SELECT `radacctid` FROM
(SELECT radacctid
FROM `radacct` `fUzDDUDv`
WHERE username = t.login
) AS `fUzDDUDv` ORDER BY `radacctid` DESC LIMIT 1
)
)
WHERE (ultimo_acct.framedipaddress = '177.23.209.194')
Unknown column 't.login' in 'where clause'.
UPDATE:
Yes, that would solve a problem. I created this sub query why I'm using the Yii Framework, and the has_one relationships there is no limit, ie if one 'cliente' with millions of 'acct', the framework seeks all 'acct', to take only one this gives some GB of traffic and is very slow. To solve, I used the subquery seeking only the newest id to get the 'cliente' and the last 'acct' and make it work in Active Record, until then everything was fine, but the search was slow estremamente to seek a record took 40 seconds, then I discovered that the problem was in the 'ORDER BY' (radacctid is an index and tables are innodb), hence I did to solve the 'ORDER BY' outside the subquery, then resolvou, the problem that the subquery column the table 'cliente' (t.login) is like there, as I explained above.
I've tried also sort by another field, eg 'acctstarttime', and continued slow, only solved when I did it this way:
SELECT `radacctid` FROM
(SELECT radacctid
FROM `radacct` `fUzDDUDv`
WHERE username = t.login
) AS `fUzDDUDv` ORDER BY `radacctid` DESC LIMIT 1
UPDATE:
But the problem of INNER JOIN is that if there is no result for 'acct' does not return the 'cliente'.
UPDATE
The problem is not where the t.login but it is not recognized as existing within the subquery that I can not put 'out' if the order is not slow.
UPDATE
Read my comments? This is the situation. It really is only on the production server that has inserts and updates all the time.
I hope this one could help you in some way:
SELECT
COUNT(DISTINCT `t`.`id`)
FROM
`radcliente` `t`
LEFT OUTER JOIN `radcliente_endereco_instalacao` `endereco_instalacao`
ON (`endereco_instalacao`.`cliente_id`=`t`.`id`)
LEFT OUTER JOIN `radcliente_telefone` `telefones`
ON (`telefones`.`cliente_id`=`t`.`id`)
LEFT OUTER JOIN `radcliente_email` `emails`
ON (`emails`.`cliente_id`=`t`.`id`)
LEFT OUTER JOIN `radmetodo_cobranca` `metodo_cobranca`
ON (`metodo_cobranca`.`cliente_id`=`t`.`id`)
AND (metodo_cobranca.arquivo = 'nao')
INNER JOIN
(
SELECT `ultimo_acct_INNER`.*
FROM
`radacct` AS `ultimo_acct_INNER`
INNER JOIN
(
SELECT `fUzDDUDv`.`username` AS `maxID_username`, MAX(`radacctid`) AS `maxID_radacctid`
FROM `radacct` `fUzDDUDv`
GROUP BY `fUzDDUDv`.`username`
) AS `radacct_MAX_ID`
ON `ultimo_acct_INNER`.`username`= `radacct_MAX_ID`.`maxID_username`
AND `ultimo_acct_INNER`.`radacctid` = `radacct_MAX_ID`.`maxID_radacctid`
) AS `ultimo_acct`
ON (`ultimo_acct`.`username`=`t`.`login`)
WHERE
(ultimo_acct.framedipaddress = '177.23.209.194')
I replaced section:
(...)
LEFT OUTER JOIN `radacct` `ultimo_acct`
ON (`ultimo_acct`.`username`=`t`.`login`)
AND (ultimo_acct.radacctid = (
SELECT `radacctid` FROM
(SELECT radacctid
FROM `radacct` `fUzDDUDv`
WHERE username = t.login
) AS `fUzDDUDv` ORDER BY `radacctid` DESC LIMIT 1
)
)
(...)
with this one:
(...)
INNER JOIN
(
SELECT `ultimo_acct_INNER`.*
FROM
`radacct` AS `ultimo_acct_INNER`
INNER JOIN
(
SELECT `fUzDDUDv`.`username` AS `maxID_username`, MAX(`radacctid`) AS `maxID_radacctid`
FROM `radacct` `fUzDDUDv`
GROUP BY `fUzDDUDv`.`username`
) AS `radacct_MAX_ID`
ON `ultimo_acct_INNER`.`username`= `radacct_MAX_ID`.`maxID_username`
AND `ultimo_acct_INNER`.`radacctid` = `radacct_MAX_ID`.`maxID_radacctid`
) AS `ultimo_acct`
ON (`ultimo_acct`.`username`=`t`.`login`)
(...)
Could you try the following modification (for optimizing performance) ?
SELECT COUNT(DISTINCT `t`.`id`)
FROM
(
SELECT DISTINCT `t_sub`.`id`
FROM
`radcliente` `t_sub`
LEFT OUTER JOIN `radacct` `ultimo_acct`
ON (`ultimo_acct`.`username`=`t_sub`.`login`)
AND (ultimo_acct.radacctid =
(SELECT `fUzDDUDv`.radacctid
FROM `radacct` `fUzDDUDv`
WHERE `fUzDDUDv`.username = `t_sub`.login
ORDER BY `fUzDDUDv`.`radacctid` DESC LIMIT 1))
WHERE (ultimo_acct.framedipaddress = '177.23.209.194')
) AS `t`
LEFT OUTER JOIN `radcliente_endereco_instalacao` `endereco_instalacao`
ON (`endereco_instalacao`.`cliente_id`=`t`.`id`)
LEFT OUTER JOIN `radcliente_telefone` `telefones`
ON (`telefones`.`cliente_id`=`t`.`id`)
LEFT OUTER JOIN `radcliente_email` `emails`
ON (`emails`.`cliente_id`=`t`.`id`)
LEFT OUTER JOIN `radmetodo_cobranca` `metodo_cobranca`
ON (`metodo_cobranca`.`cliente_id`=`t`.`id`) AND (metodo_cobranca.arquivo = 'nao')
It preselects records joining first the clients table to the 'big' table 'radacct', selecting only the distinct set of 'right' client id-s and then joining this (relatively) small set to the rest of the tables in the topmost query
I think I understand now. I have no experience with Yii framework, so for know (taking into account your last comment) I can't think of something better than the following:
SELECT COUNT(DISTINCT `t`.`id`)
FROM `radcliente` `t`
LEFT OUTER JOIN `radcliente_endereco_instalacao` `endereco_instalacao`
ON (`endereco_instalacao`.`cliente_id`=`t`.`id`)
LEFT OUTER JOIN `radcliente_telefone` `telefones`
ON (`telefones`.`cliente_id`=`t`.`id`)
LEFT OUTER JOIN `radcliente_email` `emails`
ON (`emails`.`cliente_id`=`t`.`id`)
LEFT OUTER JOIN `radmetodo_cobranca` `metodo_cobranca`
ON (`metodo_cobranca`.`cliente_id`=`t`.`id`) AND (metodo_cobranca.arquivo = 'nao')
LEFT OUTER JOIN `radacct` `ultimo_acct`
ON (`ultimo_acct`.`username`=`t`.`login`)
AND (ultimo_acct.radacctid =
(SELECT `fUzDDUDv`.radacctid
FROM `radacct` `fUzDDUDv`
WHERE `fUzDDUDv`.username = t.login
ORDER BY `fUzDDUDv`.`radacctid` DESC LIMIT 1))
WHERE (ultimo_acct.framedipaddress = '177.23.209.194')
I hope someone could help get more precise answer to your needs.

Left outer join in access?

Following query does not work in access.
SELECT Fields.FieldId, PrecisionSettings.DecimalPlaces
from Fields left outer join FieldGroup on Fields.FieldGroupId = FieldGroup.FieldGroupId
left outer join Category on FieldGroup.CategoryId = Category.CategoryId
left outer join PrecisionSettings on
Category.InputAttributesID=PrecisionSettings.AttributesID
It gives error as missing operator in query expression.
In Access you can only join two results at a time. To join more tables you need more parentheses:
SELECT
Fields.FieldId,
PrecisionSettings.DecimalPlaces
FROM
(
(
Fields
LEFT OUTER JOIN FieldGroup ON Fields.FieldGroupId = FieldGroup.FieldGroupId
)
LEFT OUTER JOIN Category ON FieldGroup.CategoryId = Category.CategoryId
)
LEFT OUTER JOIN PrecisionSettings ON Category.InputAttributesID = PrecisionSettings.AttributesID