I am using Doctrine with Zend Framework 2 to do a query on my invoices table using a sub-query.
Here's the simplified generated SQL with parameters filled in
SELECT *
FROM invoices i1
WHERE (EXISTS (SELECT * FROM invoices i2 WHERE i2.invoice_first_name IN ('stephen') OR i2.invoice_middle_name IN ('stephen') OR i2.invoice_surname IN('stephen')))
ORDER BY i1.invoice_id DESC
The problem I am having is that when I run this query in phpMyAdmin it returns all the invoices, even those that do not contain the name 'stephen'.
However when I run the sub-query separately it returns 2 rows which is correct.
SELECT * FROM invoices i2 WHERE i2.invoice_first_name IN ('stephen') OR i2.invoice_middle_name IN ('stephen') OR i2.invoice_surname IN('stephen')
So why doesn't the sub-query work with EXISTS, what am I missing?
Many thanks in advance.
As per MySQL documentation:
If a subquery returns any rows at all, EXISTS subquery is TRUE, and NOT EXISTS subquery is FALSE
Since your subquery returns some row(s), the where clause is true - for every row in the invoice table.
Related
I am using w3schools DB for my learning purpose. I have come across the doubt with SQL ALL operator. Anyone knows the solution, pls share,
Below Query returns nothing even the subquery satisfies the condition.
SELECT count(ProductName)
FROM Products
WHERE ProductID = ALL( SELECT ProductID
FROM Order_Details
WHERE Quantity > 0
);
All the entries from Order_details table has the quantity greater than 0 which satisfies the condition in the SubQuery. I confirmed this by executing the below command which returns all the entries from table.
SELECT ProductID
FROM Order_Details
WHERE Quantity > 0;
FYI,
I did import DB using the Github link-- https://github.com/AndrejPHP/w3schools-database
You may be misunderstanding what the ALL operator is supposed to do. Your query counts the names of those products whose ID matches ALL of the IDs returned by the subquery. If the subquery returns more than one distinct ID, it's obviously impossible for any one ID to match all of them at once.
Perhaps you were expecting the query to retrieve the number of records that match ANY of the IDs from the subquery? To achieve that, replace ALL with ANY in your code.
I am attempting to join the two tables below to show all the columns for the incident table and just a count of the corresponding records from the tickets table with the incident_id as the same in the incidents table.
As you can see below, none of the tickets have an incident_id assigned yet. The goal of my query is to show all of the records in the incident table with a count of the ticket_ids assigned to that ticket. I thought that this would work but it's returning only one row:
SELECT inc.incident_id, inc.title, inc.date_opened, inc.date_closed, inc.status, inc.description, issue_type, COUNT(ticket_id) as example_count
FROM fin_incidents AS inc
LEFT OUTER JOIN fin_tickets ON inc.incident_id = fin_tickets.incident_id;
What query can I use to return all of the incidents and their count of tickets, even if that count is 0?
Images:
Incident Table
Tickets Table
Result of my query
Your query should not work at all -- and would fail in the more recent versions of MySQL. The reason is that it is missing a GROUP BY clause:
SELECT inc.incident_id, inc.title, inc.date_opened,
inc.date_closed, inc.status, inc.description, inc.issue_type,
COUNT(t.ticket_id) as example_count
FROM fin_incidents inc LEFT OUTER JOIN
fin_tickets t
ON inc.incident_id = t.incident_id
GROUP BY inc.incident_id, inc.title, inc.date_opened,
inc.date_closed, inc.status, inc.description, inc.issue_type
You have an aggregation query with no GROUP BY. Such a query returns exactly one row, even if the tables referred to are empty.
Your code is not a valid aggregation query. You have an aggregate function in the SELECT clause (the COUNT()), but no GROUP BY clause. When executed this with sql mode ONLY_FULL_GROUP_BY disabled, MySQL gives you a single row with an overall count of tickets that are related to an incident, and any value from incident row. If that SQL mode was enabled, you would a compilation error instead.
I find that the logic you want is simpler expressed with a correlated subquery:
select i.*
(select count(*) from fin_tickets t where t.incident_id = i.incident_id) as example_count
from fin_incidents i
This query will take advantage of an index on fin_tickets(incident_id) - if you have defined a foreign key (as you should have), that index is already there.
Simple query, i have a table with clientID and cardKey. One client can have many cards. Query is to find all cards belonging to client 1
I am using mysql work bench, it executes the query normally with no errors but returns no results
SELECT cID, cardKey
FROM client_cards
where `cID` = 1 ;
Your query is correct, but in the client_cards table there is no row that has cID = 1.
Can I divide the values in a column by the number of rows returned in the query, using a single query?
For example, I select some numeric value from a table based on some condition:
select value from table where ...
Let's say it returns N rows and I want the returned values divided by the number of rows returned:
select value / N from table where ...
It can be done with several queries (e.g. after the first query, I query the number of rows and do the query again). But can it be done in a single query with some SQL trick without query condition duplication, so that the actual selection (the WHERE part) which may be complicated runs only once?
You can do it in a single query, but as far as I know, with mysql you have to repeat the condition:
select
value/#cnt from
table1
INNER JOIN (select #cnt = count(*)
FROM table1 WHERE [the same condition as in main query]) ON (1=1)
WHERE condition
Or you can just
SELECT value/(SELECT COUNT(*) FROM table1 WHERE ...)
FROM table1
WHERE ...
I believe optimizer should generate the same execution plan for both queries.
1. SELECT * FROM instalmentsdetails WHERE instalmentName='Third Installment'AND studentFeeId='1'
2. select max(`receiptNo`)as `receiptNo` FROM instalmentsdetails
Table instalmentsdetails
instalmentsDetailsId
studentFeeId
receiptNo
instalmentName
amount
dueDate
fineAmt
waivedAmt
scholarShip
grandTotal
status
Little confused .How to merge this two query statement into one query statement
P.S: One statement checks for the condition and the other checks for the max of receiptNo in that table
I want both the values in one query
Is this what you want?
SELECT max(`receiptNo`) as `receiptNo`
FROM instalmentsdetails
WHERE instalmentName='Third Installment' AND studentFeeId='1'
Update: how about this:
SELECT *
FROM instalmentsdetails as inds
INNER JOIN (
SELECT max(`receiptNo`) as `maxreceiptNo`
FROM instalmentsdetails
) as maxt
WHERE inds.instalmentName='Third Installment' AND inds.studentFeeId='1'
This applies the filter to the table, then adds an extra column (the maximum receiptNo)
Assuming the goal is to get:
a list of instalmentsdetails with specific a instalmentName and studentFeeId
global maximum
SELECT *, 0 AS receiptNo FROM instalmentsdetails WHERE instalmentName='Third Installment'AND studentFeeId='1'
UNION
select *, max(`receiptNo`) as `receiptNo` FROM instalmentsdetails
Update
Apparently the OP simply wants to consolidate separate query results into a single row. In that case:
SELECT
*,
(SELECT max(`receiptNo`) FROM instalmentsdetails) AS maxReceiptNo
FROM instalmentsdetails WHERE instalmentName='Third Installment'AND studentFeeId='1'
From all the reading, Matt is correct, but maybe I can help explain what he's doing...
The first part of the query (From InstalmentsDetails WHERE YourCondition) will get all records that qualify for the condition.
THEN, by doing a JOIN to the second query (select max( 'receiptNo' ) from... with no where clause ) will ALWAYS return a single row, single column of the maximum receipt without regard to ANY criteria.
This creates an implied Cartesian result. Join everything in the first table with every record in the second. Since there is no explicit join condition, every row will get the same "max()" value as a returned column. And since there will only be one record in the select max() call, you never worry about duplicates.
Now, if you wanted the maximum receipt within the same criteria, you would just copy that same criteria to the select max() query portion.