I have two MySQL queries:
First:
SELECT DISTINCT (broker.broker_id),company_id ,broker_name,company_name,mobile1_no,email,pan_card_num,broker_id,broker_id,company_id
FROM broker_firm AS broker_firm
LEFT JOIN broker ON broker_firm.company_id = broker.firm_id
AND broker_firm.is_active =1
AND broker.is_active =1
This query is generating 331 results.
Second:
SELECT COUNT( broker.broker_id ) AS tot
FROM broker_firm AS broker_firm
LEFT JOIN broker AS broker ON broker_firm.company_id = broker.firm_id
AND broker_firm.is_active =1
AND broker.is_active =1
This query is generating 289 results.
Can anyone please tell me the reason why? I expected both of the results to be same. Or maybe, the Count(*) result to be greater.
Thanks in advance
When you do a left join, the logic is simple: keep all the rows in the first table, regardless of whether the condition in the on clause is true. If the condition is false, then all the columns in the second table get a value of NULL.
When you do an inner join, the logic is to keep all rows in the first table.
In the first query, the additional conditions are in the on clause. Hence, all rows in the first table are kept (and don't forget that the join itself may result in duplicates). In the second query, the where clause has a condition broker.is_active = 1. This condition will fail when is_active is NULL -- which is what happens when the records don't match. In other words, the condition is turning the left join into an inner join.
EDIT:
The idea is the same. The second query is counting the matching records. count(broker.broker_id) counts the non-NULL values for that column. This is the same as doing an inner join.
The first query is counting all records. select distinct selects distinct values of all the columns. Your syntax is a bit confusing, because it suggests that you just want the distinct value of one column. But that is not how it works. Because you have columns from both tables in the select, the non-matching brokers will have their company information on the row, making that row distinct from all other rows.
why dont you use both in one query ?
SELECT broker.broker_id,company_id ,broker_name,company_name,mobile1_no,email,pan_card_num,broker_id,broker_id,company_id,COUNT( broker.broker_id ) AS tot
FROM broker_firm AS broker_firm
LEFT JOIN broker ON broker_firm.company_id = broker.firm_id
AND broker_firm.is_active =1
AND broker.is_active =1
GROUP BY broker.broker_id
First query counts all firms, you have 42 firms with no broker.
try
select count(broker_firm.company_id)
FROM broker_firm
where broker_firm.company_id not in (select firm_id from broker)
Related
I wrote 2 queries expecting them to yield same results, yet they turned out to be different.
I would like to ask why they return different results?
I am more confident that the 1st query returns what I want, so how should I amend the 2nd query? Thx!
1st SQL query:
SELECT
Product.*,
Status.*,
Price.*
FROM Product
LEFT JOIN Status
ON Product.MarketplaceId = Status.ListingId
LEFT JOIN Price
ON Product.ProductId = Price.Id
LIMIT 15;
2nd SQL query:
SELECT
Product.*,
Status.*,
Price.*
FROM Product
LEFT JOIN Status
ON Product.MarketplaceId IN
(
SELECT ListingId FROM Status
)
LEFT JOIN Price
ON Product.ProductId IN
(
SELECT Id FROM Price
)
LIMIT 15;
Without seeing the data, I don't understand why a different result. However, if you intend to have only one per product, I would change the second query to use DISTINCT. If the subquery returns multiple rows for whatever the condition, it will return that many rows even if a single product.
Don't use IN ( SELECT ... ) if there is an alternative; it is often slower.
Don't use LEFT JOIN if the matching row in the 'right' table will always be there. It confuses readers.
The reason for different results is the lack of ORDER BY. (As Akina mentioned.) Removing the LIMIT would probably cause the two queries to deliver all the same rows, though probably in a different order.
My SQL query doesn't return an output that suppose to be specified by my where clause.
Here is my query:
SELECT
transaction_details.transaction_id
,transaction_details.transaction_number
,transaction_details.product_id
,Products3.ProductName
FROM transaction_details
INNER JOIN Products3
ON transaction_details.product_id = Products3.productID
INNER JOIN transaction_status
ON transaction_details.transaction_id = transaction_status.transaction_id
WHERE status_of_transaction = 'review'
This query should return me table rows with a status_of_transaction = 'review'.
Here is my table which contains the status_of_transaction
I tried DISTINCT but its not working.
and this is the output I always get:
is there something wrong with my query its is returning table row which was not specified by my WHERE clause?
There are multiple rows generated by the set (remember this is all set theory) - you are missing a Foreign Key/Primary Key (FK/PK) relationship in the JOIN. I'll bet you missed a column in the INNER JOIN "ON" statement. There are probably two columns necessary to JOIN on to find the proper solution.
I suggest either picking it apart table by table, or using select * and look for the difference in the column values between each row. One column should be different - which you currently cannot see (i.e. hidden) because the column is not in the current SELECT statement.
Try this...
SELECT
transaction_status.*
FROM transaction_details
INNER JOIN Products3
ON transaction_details.product_id = Products3.productID
INNER JOIN transaction_status
ON transaction_details.transaction_id = transaction_status.transaction_id
WHERE status_of_transaction = 'review'
I believe the issue is with the transaction_status join. The transaction_id is the same for both rows in transaction_details - which matches TWO rows in transaction_status. SQL will create 4 rows -- two rows that match "review" and two rows for "replied" (remove the WHERE to see them). This is a cross join of sorts.
Does the _status table also contain transaction_number? There needs to be a way to JOIN to the single row in transaction_details to a single row in transaction_status. Somehow that _status row belongs to the _details row. Look at (or ask the DBA) the PK/FK definitions for both tables.
Not knowing your schema - I would guess the solution is....
SELECT
transaction_details.transaction_id
,transaction_details.transaction_number
,transaction_details.product_id
,Products3.ProductName
FROM transaction_details
INNER JOIN Products3
ON transaction_details.product_id = Products3.productID
INNER JOIN transaction_status
ON transaction_details.transaction_id = transaction_status.transaction_id
-- ADDED NEXT LINE
AND transaction_details.transaction_number = transaction_status.transaction_number
-- END Change
WHERE status_of_transaction = 'review'
Most likely one of the inner joins is matching more than one row, so it generates two rows in the output set. Run the query with:
select transaction_details.transaction_id
, Products3.product_id
, transaction_details.detail_id
to examine which join is the culprit.
Below is my query I used to give data to jquery datatables.
From this query, I need the result as well as the total rows count. So, I return the total rows count as subquery.
SELECT m.*,
(SELECT COUNT(*)
FROM member m
INNER JOIN relationship r ON m.ID = r.Relative_ID
WHERE r.Member_ID=33) as TotalRows
FROM member m
INNER JOIN relationship r ON m.ID = r.Relative_ID
WHERE r.Member_ID=33
ORDER BY 1 asc
LIMIT 0, 10
Is the subquery to take totalrows running once or 10 times or many?
The WHERE condition is applied before the SELECT statement, so you'll only be doing one subquery. This is the same reason for not being able to use SELECT aliases in WHERE conditions.
Thhere is only a single sub-query, and this isn't joined to anything else out of the query, so I would assume it only runs once.
A query execution plan would give you a definative answer.
Given the following query…
SELECT DISTINCT *
FROM PAS_Post
WHERE post_user_id = 21
GROUP BY post_post_id
UNION
SELECT DISTINCT PAS_Post.*
FROM PAS_Follow LEFT JOIN PAS_Post ON (
PAS_Follow.folw_followed_user_id = PAS_Post.post_user_id
)
WHERE PAS_Follow.folw_follower_user_id = 21
GROUP BY post_post_id
ORDER BY post_posted_date DESC
I always get a row in the results that is just NULL's, unfortunately I need to preserve some NULL values in the data as the Post's table (PAS_Post) holds different types of information.
Can anyone steer me in the right direction to get rid of this null row.
I do not want or need the last row here
You're using a (left) outer join in the second part of the UNION, so any cases that do not satisfy the join criteria will result in data from the table on the left of the join (PAS_Follow), but NULL in every column of the table on the right of the join (PAS_Post); the subsequent selection only of columns from the latter table results in the NULL rows that you observe. Therefore, the simplest solution is to use an inner join (that completely excludes records where the join criteria is not met).
However, in your case, it appears that your query can be greatly simplified by simply using two possible conditions in a filter on the joined tables rather than a UNION:
SELECT p.*
FROM PAS_Post AS p
JOIN PAS_Follow AS f ON f.folw_followed_user_id = p.post_user_id
WHERE p.post_user_id = 21
OR f.folw_follower_user_id = 21
ORDER BY p.post_posted_date DESC
I have excluded the GROUP BY clause on the assumption that post_post_id is the primary key (or at very least is UNIQUE) in your PAS_Post table. If that assumption is incorrect, you may want to reintroduce it—but beware that MySQL will indeterminately select the values that will be returned from each group.
I have a QUERY which is like
SELECT COUNT(*) as cnt
FROM tbl_docatrtypegroupdoctype,
tbl_doctype,
tbl_docatrtypegroup
WHERE 1=1
AND
(tbl_doctype.doctype_name like '%Payment%'
OR tbl_doctype.doctype_name like'% Payment'
OR tbl_doctype.doctype_name like ' Payment%' )
LIMIT 1
Now in the above query I need to count the number of records in table "tbl_docatrtypegroupdoctype" under the conditons given in where clause, whenever i execute the query, I get 77 count, but actual count in DB is 12.
What could be the problem with this query and how can I rectify it?
Ant help will be appriciated
Thanks
You need to specify your join conditions. What happens if you don't is a cross product which is not what you want.
SELECT COUNT(*) as cnt
FROM tbl_docatrtypegroupdoctype JOIN
tbl_doctype on (THE CONDITION) JOIN
tbl_docatrtypegroup on (THE CONDITION)
Alternatively the JOIN conditions can be spefified in the WHERE clause.
In the where clause:
WHERE table1.field1 = table2.field2 AND table2.field3 = table3.field4
The fields that you join on must be semantically related in some way of course.
You need to apply all join-conditions between the three tables.