Is it possible to give an alias to a joined table in MySQL?
For example
Select *
From Customers
Natural Join Transaction as CT
Where (Select Count(CT.Customer_ID) ) >= 2
Would CT reference the joined table or the Transaction table?
And if it references the Transaction table how do I reference the joined table in a sub query?
No, you cannot do this in MySQL. In other databases, you could use a CTE for this purpose. (And in any database, you could use a temporary table, but that is not a good solution.)
Note: Do not use natural join. It is a bug waiting to happen.
To expression your query, use either an ON or USING clause. For your query, it would be something like this:
Select c.*, ct.*
From Customers c Join
Transaction as CT
ON c.Customer_ID = CT.Customer_ID JOIN
(select t2.Customer_ID, count(*) as cnt
from Transaction t
group by t2.CustomerId
where cnt >= 2
) cct
ON cct.Customer_ID = cct.Customer_Id;
Based on your comment:
Grab all customers who have 2 or more transactions
Here's one option using exists:
select *
from customers c
where exists (
select 1
from transaction t
where c.customerid = t.customerid
having count(*) > 1
)
Related
I have 14000 records in my sql table. They have columns ID, test_subject_id and date_created. I want to fetch all the records that have been created within a time difference of 3 minutes(difference in date_created values) and both records should have the same test_subject_id.
You should use a self join, I assume inner join is what will work for you:
SELECT a.ID, a.date_created, b.ID, b.date_created
FROM accounts a
INNER JOIN accounts b
ON a.test_subject_id = b.test_subject_id
AND TIMESTAMPDIFF(MINUTE,a.date_created,b.date_created) = 3
Note: TIMESTAMPDIFF is used assuming date_created has type datetime, details here.
You can use EXISTS:
SELECT t1.*
FROM tablename t1
WHERE EXISTS (
SELECT 1
FROM tablename t2
WHERE t2.test_subject_id = t1.test_subject_id
AND ABS(TIMESTAMPDIFF(SECOND, t1.date_created, t2.date_created)) <= 180
)
ORDER BY t1.test_subject_id, t1.date_created;
There are four table Bill_entry,Customer,Chit,Cash. I want to join table Customer with table Bill_entry in following query where they have common column customer_id. Goal here is by using customer_id i want to print customer_name too in one query.
i have tried but couldn't get correct syntax
Initial code before including Customer table :
SELECT Bill_entry.*
FROM (SELECT * FROM Chit UNION SELECT * FROM Cash) as t1 RIGHT JOIN
entry
ON (Bill_entry.bill_no = t1.bill_no)
WHERE t1.bill_no IS NULL
MY tries :
SELECT Bill_entry.*, Customer.customer_name
FROM ((SELECT * FROM Chit UNION SELECT * FROM Cash) as t1 RIGHT JOIN entry ON (Bill_entry.bill_no = t1.bill_no) WHERE t1.bill_no IS NULL)customer where Bill_entry.customer_id = Customer.Customer_id
Just add in another JOIN:
SELECT e.*, cu.customer_name
FROM bill_entry e LEFT JOIN
(SELECT * FROM Chit
UNION ALL -- assume you don't want to remove duplicates
SELECT * FROM Cash
) c
entry e
ON e.bill_no = c.bill_no LEFT JOIN
Customer cu
ON cu.customer_id = e.Customer_id
WHERE c.bill_no IS NULL;
Note some changes.
The UNION --> UNION ALL. I assume you don't want to remove duplicates or incur the overhead for trying to remove them.
RIGHT JOIN --> LEFT JOIN. It is usually much simpler to think about LEFT JOINs -- keep all the rows in the first table and then matching rows in the others.
The JOIN conditions are all in ON clauses, not the WHERE clause.
Looking at the following example:
SELECT *
FROM customers
WHERE EXISTS
(SELECT *
FROM order_details
WHERE customers.customer_id = order_details.customer_id)
;
Which differences are there from an equivalent inner join-based query between the two tables that retrieves the same resultset?
I'm concerned about the technical/performance aspect, not the readability/mantainabilty of the code.
With an EXISTS clause you select all customers for which exist at least one order_details record.
SELECT *
FROM customers c
WHERE EXISTS (SELECT * FROM order_details od WHERE od.customer_id = c.customer_id);
With a join you'd select again those customers. However, you'd select each as often as there exists an order_detail for them. I.e. you'd have many duplicates.
SELECT c.*
FROM customers c
JOIN order_details od ON c.customer_id = od.customer_id;
You can remove the duplicates from your results with DISTINCT so as to get each customer only once again:
SELECT DISTINCT c.*
FROM customers c
JOIN order_details od ON c.customer_id = od.customer_id;
But why generate all the duplicates only to have to remove them again? Don't do this. Only join when you really want joined results.
Another option, which I consider even more readable than an EXISTS clause is the IN clause by the way. This would be my way of writing the query:
SELECT * FROM customers WHERE customer_id IN (SELECT customer_id FROM order_details);
The EXISTS would be logically working as follows
for x in (select * from customers)
loop
-- check if x.customer_id exists in order_details table.
---if yes
--output the customer tables row
-- else
--ignore
end if;
end loop;
So in the exists query the plan would generally be using a nested loop(Not a hard-fast rule though)
The JOIN query does the logical equivalent as follows
for x in (select * from customers)
loop
--for each row in customer
-- fetch records from order_details which match this condition
select * from order_details where customer_id=x.customerid
end loop;
EXISTS() is called a "semi-join". It starts a JOIN, but then stops when it finds the first match. For this reason, EXISTS will be faster than any equivalent JOIN.
Also, EXISTS( SELECT * ... WHERE ... ) does not really care about the *. It will use whatever index is optimal to discover the presence or absence of rows matching the WHERE, then it returns 1 or 0 (meaning "true" or "false").
Of course, if a LEFT JOIN is going to return 0 or 1 row, never more, then there is not much performance difference. Except that the LEFT JOIN will return values from the table.
I have a temporary table named Days created as
CREATE TEMPORARY TABLE days (start_date DATETIME)as
SELECT DATE_ADD(begin_date, INTERVAL n - start_health_post_id DAY) as
start_date FROM NOF
ORDER BY n
LIMIT nofdays;
Now I want to have a cross join with a bunch of select statements that perform inner join
So, I tried this ways
Select * from days
cross join
(
Select practices.*, providers.*, practice_locations.*
from practices
Inner Join providers on practices.health_post_id = providers.health_post_id
Inner join practice_locations on practices.health_post_id =practice_locations.health_post_id
);
But It gives an error saying , every derived table must have its own alias.
please help!
Set an alias for your sub-query like:
Select * from days
cross join
(
Select practices.*, providers.*, practice_locations.*
from practices
Inner Join providers on practices.health_post_id = providers.health_post_id
Inner join practice_locations on practices.health_post_id =practice_locations.health_post_id
) t1;
I set t1 as alias.
I want to select two tables in one query but it doesn't seem to work. I have tried nested select but I just got sql_error:
Subquery returns more than 1 row
Here is my query:
SELECT `client`.`id` as client_id,
(SELECT `org`.`name` FROM `org`) as organization
FROM `client`
What is the better way to query two tables?
Here is my expected result:
client_id = [1,2,3,4,5]
organization = [x,y,z]
This will work but it isn't what you want i think.
SELECT `client`.`id` as client_id, `org`.`name` as organization FROM `org`, `client`
This will give you a cross product of all rows in org with all rows in client. Maybe you want something like this:
SELECT `client`.`id` as client_id, `org`.`name` as organization FROM `org` JOIN `client` ON `client`.`memberOf` = `org`.`id`
The JOIN will connect rows of both tables where column memberOf in table client is equal to column id in table org
You should use join queries to join two or more tables. you can visit https://dev.mysql.com/doc/refman/5.0/en/join.html
Example of the join query:
SELECT t1.name, t2.salary
FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;