I have a table, customers, it looks sort of like this:
CustomerID cobuyerID
001 005
002
003 006
004
005
006
Can I use WITH to get a set of customers and a set of cobuyers? So something like:
;WITH Customers as
(
SELECT * FROM Customers where (* WHERE CustomerID not in cobuyerID*)
),
Cobuyer as
(
SELECT * FROM Customers where (*WHERE CustomerID only in cobuyerID*)
),
I suppose you could do it with a LEFT JOIN or an exists...
I don't think though you can have your CTE defined as customers and select from the customers table... two objects same name seems like the DB engine would get confused.
Here's a left join...
;WITH C2 as
(
SELECT *
FROM Customers A
LEFT JOIN Customers B
ON A.CustomerID = B.CoBuyerID
WHERE B.CobuyerID is Null)
),
Cobuyer as
(
SELECT *
FROM C2 A
LEFT JOIN Customers B
on A.CoBuyer = B.CustomerID
WHERE B.CustomerID is null
)
Related
CUSTOMERS
NAME
ID
ORDERS
CID
ITEMS
New customer orders in orders table have new data record like:
CID 134 - CAR
CID 135 - PHONE
CID 134 - TEA
I need to select only customers that have 1 record in the orders table, in dat above its CID 135
IDN=CID
I need to select IDN that have only one ITEMS record, I tried:
SELECT customers.name, orders.items
FROM customers JOIN orders
WHERE Items > 2
but doesn't work :(
You just need to modify your where clause. This query will return only customers that have exactly one row in the orders table.
SELECT customers.name,
orders.items
FROM customers
LEFT JOIN orders
on customers.ID = orders.CID
WHERE customers.ID IN (SELECT CID from orders GROUP BY CID HAVING COUNT(*) = 1)
Try adding an ON statement for your join. This tells SQL how to connect the two tables.
SELECT
customers.name
, orders.items
FROM customers
JOIN orders
on customers.ID = orders.CID
WHERE Items > 2
You must add a another subquery which count the numbers,
CREATE tABLE customers (ID int, name varchar(10))
INSERT INTO customers VALUES (1,'A'),(2,'b')
CREATE tABLE orders (ID int,CID int,items varchar(10))
INSERT INTO orders VALUES (1,1,'car'),(2,1,'car2'),(3,2,'car'),(4,2,'car2'),(5,2,'car2')
SELECT
customers.name
, orders.items
FROM customers
JOIN orders
on customers.ID = orders.CID
INNER JOIN (SELECT COUNT(*) countr,CID FROM orders GROUP BY CID) o1 on o1.CID = orders.CID
WHERE countr > 2
name | items
:--- | :----
b | car
b | car2
b | car2
db<>fiddle here
You can do:
select * from customers
where id in (
select cid from orders group by cid having count(*) = 1
)
I am forming a sql query like below which gives me an error that i cannot use m1.id in inner where clause.
SELECT
c.id,
m.member_no,
mc.card_no
FROM
customer AS c
LEFT JOIN
(
SELECT
*
FROM
membership
WHERE
creation_date = (SELECT MAX(creation_date) FROM membership AS m1 WHERE m1.cust_id = 123)
) AS m ON m.cust_id = c.id
LEFT JOIN
(
SELECT
*
FROM
member_card
WHERE
emboss_date = (SELECT MAX(emboss_date) FROM member_card AS mc1 WHERE mc1.membership_id = m.id)
) AS mc ON mc.membership_id = m.id
WHERE
c.id = 123
Table :
Customer, Membership, Member_card.
Customer can have many membership and each membership can have many member_card.
Table Customer
id name address
1 amit abc
2 mohit xyz
3 rahul asdf
4 ganesh pqr
Table membership
id member_no creation_date cust_id
21 123 21-09-1978 1
31 234 21-09-1988 2
41 345 21-09-1998 1
51 456 21-09-1977 2
Table member_card
id card_no membership_id emboss_date
111 12345 21 21-09-1978
222 23456 31 21-09-1977
333 34567 21 21-09-1976
444 456789 41 21-09-1975
cust_id is foriegn Key in membership table
membership_id id foreign key in member_card table
Now, i want the customer details of all customer table with latest member_no(w.r.t creation_date) and card_no(w.r.t emboss_date), Even if a customer does not have membership, the customer details should be there. refer the query above i made
So, there should be one record for one customer, i.e the final result should contain 4 rows with data from all three tables
The joins should go with proper subquery
select
c.id, m.member_no, mc.card_no
from customer c
left join (
select * from membership m
where creation_date = (select max(creation_date)
from membership where cust_id = m.cust_id)
) m on m.cust_id = c.id
left join (select * from member_card mc
where emboss_date = (select max(emboss_date)
from member_card where membership_id = mc.membership_id)
) mc on mc.membership_id = m.id
where c.id = 123
Other version with aggregation instead of correlation
select
c.id, m.member_no, mc.card_no
from customer c left join (
select cust_id, max(creation_date) creation_date
from membership
group by cust_id) m
on m.cust_id = c.id left join (
select membership_id, max(emboss_date) emboss_date
from member_card mc
group by membership_id) mc
on mc.membership_id = m.cust_id
where c.id = 123
I would like to seek the advice of some sql experts.
I wrote sql statement for getting authors names from staff and alumni table. Some author's name will be in both tables. So the logic is if the author name is in staff, use that otherwise look for alumni table.
Here is my sql statement, seems fine but it is showing same author name from both staff and alumni table.
SELECT DISTINCT AP.Author_name, P.people_id, P.Name, P.Journal_name, AP.Author_sortorder FROM `Paper_Author` AS AP LEFT JOIN `People` AS P ON ( AP.Author_id = P.people_id ) WHERE AP.Paper_id =3838
UNION
SELECT DISTINCT AN.Author_name, N.People_id, N.Name, N.Journal_name, AN.Author_sortorder FROM `Paper_Author` AS AN LEFT JOIN `Alumni` AS N ON ( AN.Author_id = N.People_id ) WHERE AN.Paper_id =3838 ORDER BY Author_sortorder LIMIT 0 , 30
Result:
people_id-- Author_name-- Journal_name--
1 Name1 A1
2 Name2 B1
3 Name3 C1
3 Name3 C1
4 Name4 D
4 Name4
Expected Result :
people_id-- Author_name-- Journal_name--
1 Name1 A1
2 Name2 B1
3 Name3 C1
4 Name4 D
This can probably be solved by an additional select using the original result as a subquery
SELECT DISTINCT * FROM (
SELECT DISTINCT AP.Author_name, P.people_id, P.Name, P.Journal_name, AP.Author_sortorder FROM `Paper_Author` AS AP LEFT JOIN `People` AS P ON ( AP.Author_id = P.people_id ) WHERE AP.Paper_id =3838
UNION
SELECT DISTINCT AN.Author_name, N.People_id, N.Name, N.Journal_name, AN.Author_sortorder FROM `Paper_Author` AS AN LEFT JOIN `Alumni` AS N ON ( AN.Author_id = N.People_id ) WHERE AN.Paper_id =3838 ORDER BY Author_sortorder LIMIT 0 , 30
);
The difficulty with this problem is that you might need information from either the People or Alumni tables. We would like to just join to a single table containing the right information. Much of the complexity of the below query is in creating a table which contains the right metadata for each person.
SELECT
pa.Author_name,
pa.Author_sortorder,
t1.people_id,
t1.Name,
t1.Journal_name
FROM Paper_Author pa
LEFT JOIN
(
SELECT people_id, Name, Journal_name, 0 AS source
FROM People
UNION ALL
SELECT people_id, Name, Journal_name, 1
FROM Alumni
) t1
ON pa.Author_id = t1.people_id
INNER JOIN
(
SELECT people_id, MIN(source) AS source
FROM
(
SELECT people_id, 0 AS source
FROM People
UNION ALL
SELECT people_id, 1
FROM Alumni
) t
GROUP BY people_id
) t2
ON t1.people_id = t2.people_id AND
t1.source = t2.source
WHERE
pa.Paper_id = 3838;
The various tables and their columns are:
1)Course
course_id
course_name
duration
fee
2)Registration
course_id
stud_id
doj
3)Student
stud_id
first_name
last name
city
dob
I have tried:
SELECT
C.COURSE_ID,
C. COURSE_NAME,
COUNT(R.COURSE_ID) * FEES AS TOTAL_FEES
FROM
COURSE C,
REGISTRATION R,
WHERE
C.COURSE_ID = R.COURSE_ID
GROUP BY
R.COURSE_ID
SELECT c.cource_id, c.course_name, (totalNumberOfStudentPerCourse.totalNumberOfStudent * c.fee) as totalFee
FROM Course c
INNER JOIN
(SELECT r.course_id, COUNT(r.stud_id) as totalNumberOfStudent
FROM Registration r
GROUP BY r.course_id) totalNumberOfStudentPerCourse ON c.course_id = totalNumberOfStudentPerCourse.course_id
the subquery creates a totalNumberOfStudentPerCourse table that looks like this:
course_id totalNumberOfStudent
1 4
2 2
example:
course:
course_id course_name fee
1 math 300
2 english 200
registration:
course_id stud_id
1 1
1 2
1 3
1 4
2 5
2 6
result:
course_id course_name totalFee
1 math 1200
2 english 400
You can use a select on your group by query and then join it with the course table to use the rest of its fields.
SELECT aa.course_id, aa.course_name, aa.fee * _aa.total_registrations AS total_fees
FROM course AS aa
LEFT JOIN (
SELECT course_id, COUNT(*) as total_registrations
FROM registration
GROUP BY course_id
) AS _aa
ON aa.course_id = _aa.course_id
ORDER BY aa.course_name ASC
select c.courseid, c.coursename, c.fees * aa.tr as TOTALFEES
from course c
LEFT JOIN (
select courseid,COUNT(*) as tr
from registration
group by courseid
) aa
ON c.courseid = aa.courseid
order by c.courseid;
select courseid,coursename,(tsp_course.totalstd * c.fees) as TOTALFEES
from course c
inner join(select r.courseid,count(r.courseid) as totalstd
from registration r
group by r.courseid) tsp_course using(courseid)
order by courseid;
This is what you are looking for:
Select course.course_id,course.course_name,(count(reg.stud_id)*course.fee)
From Course course INNER JOIN Registration reg
ON course.course_id=reg.course_id
GROUP BY course.course_id,course.course_name,course.fee
The intersect keyword is not available in mysql. I want to know how to implement the following in mysql db. My tables are:
customer(cid,city,name,state)
orders(cid,oid,date)
product(pid,price,productname)
lineitem(lid,pid,oid,totalquantity,totalprice)
I want the products bought by all the customers of a particular city 'X'. i.e. every customer in city 'x' should have bought the product. I managed to select the oid's and the pid's of customers living in that particular city. Now I should select the pid's which is present in all the oid's.
Example.
Oid Pid
2400 1
2400 2
2401 3
2401 1
2402 1
2403 1
2403 3
The answer from the above input should be 1 because it is present in all oid's. The query which I used to get the oid's and pid's:
select t.oid,l.pid
from lineitem l
join (select o.oid,c1.cid
from orders o
join (select c.cid
from customer c
where c.city='X') c1
where o.cid=c1.cid) t on l.oid=t.oid
Now I need to intersect all the oid's and get the result.The query should not be dependent on data.
Try:
select pid, count(*)
from (select t.oid, l.pid
from lineitem l
join (select o.oid, c1.cid
from orders o
join (select c.cid from customer c where c.city = 'X') c1
where o.cid = c1.cid) t
on l.oid = t.oid) x
group by pid
having count(*) = (select count(*)
from (select distinct oid
from lineitem l
join (select o.oid, c1.cid
from orders o
join (select c.cid
from customer c
where c.city = 'X') c1
where o.cid = c1.cid) t
on l.oid = t.oid) y) z
I think you can achieve what you want by using IN