I want to show all articleNames that have more than 3 bids. It is also the number of the Bids with.
I did it so, but I really don't understand the inner joins. I understand it so that inner join is usefull to connect each table.
SELECT ArticleName, bidTime
FROM BID b inner join OFFER o
on b.OID = o.OID;
WHERE (bidTime- auctionEndDate) > 3;
To understand SQL JOINS please refer to the article bellow:
http://www.sql-join.com/sql-join-types/
It graphically explains joins and this is the basic that everyone should know regarding SQL.
The query for getting offers with 3+ bids
SELECT o.articleName
FROM offer o
INNER JOIN bid b on o.oid = b.oid
WHERE b.bidTime < o.auctionEndDate
group by o.oid, o.articleName
having count(b.bid) >= 3;
Related
I'm creating code that simulates patients going to the hospital to test for covid-19. I need to consult the youngest patient that tested positive (the patients only have different ages), but I can't get the information right about the patient (patient_name, codepatient). I've tried using subquery:
SELECT P.patient_name, P.patient_age, T.results
FROM patient P
LEFT OUTER JOIN testing T on T.codepatient=P.codepatient
WHERE P.patient_age =
(SELECT min(P.patient_age)
FROM patient P);
But I can't find a way to retrieve the testing = 'Positive'. I also tried this:
SELECT P.patient_name, min(P.patient_age), T.results, T.codepatient
FROM patient P
INNER JOIN testing T on T.codepatient=P.codepatient
WHERE T.results = 'Positive';
Unfortunately it shows only the right age, the name and code are selected from the oldest patient.
I'm a college student and I'm beginning to use MySQL. English is my second language, i'm trying my best to ask this question clearly, i apologize if i make mistakes.
You can include the test for Positive in the subselect:
SELECT p.patient_name, p.patient_age, t.results
FROM patient p
INNER JOIN testing t
on t.codepatient = p.codepatient
WHERE p.patient_age = (SELECT min(p.patient_age)
FROM patient p
INNER JOIN testing t
ON t.codepatient = p.codepatient
WHERE t.results = 'Positive');
db<>fiddle here
You need to order the data by age, then use LIMIT 1 to get one record
SELECT P.pacient_name, P.pacient_age, T.results, T.codepacient
FROM pacient P
INNER JOIN testing T on T.codepacient=P.codepacient
WHERE T.results = 'Positive' ORDER BY p.pacient_age LIMIT 1
I am having some problems with this homework question:
I have been able to successfully complete almost all of the query except for the "Only include states with at least 3 diamond mines". I would like to ask how I can add this part to the query.
select I.state, sum(P.capacity)
from Infrastructure I
natural join Mine M
join produces P
on P.mine = M.entryno
join Commodity C
on C.comID = P.commodity
where C.name like '%Diamond%'
group by I.state
If your attempt works fine other than condition mentioned in question following query should work:
select I.state, sum(P.capacity)
from Infrastructure I
natural join Mine M
join produces P
on P.mine = M.entryno
join Commodity C
on C.comID = P.commodity
where C.name like '%Diamond%'
group by I.state
having count(P.mine) >=3;
It will count the no. of commodity for each state as you already has group by on State.
Hope it helps!
Use a HAVING clause to count and assert the number of diamond mines:
SELECT
I.state,
SUM(P.capacity)
FROM Infrastructure I
NATURAL JOIN Mine M
INNER JOIN produces P
ON P.mine = M.entryno
INNER JOIN Commodity C
ON C.comID = P.commodity
WHERE
C.name LIKE '%Diamond%'
GROUP BY
I.state
HAVING
COUNT(*) >= 3;
Note: Natural join seems error prone to me and could break at some point. The best thing to use are explicit joins.
I'm having some trouble trying to get all the data out of this database in one query.
Here is the Database scheme
I know that there is a way to do this with a join but i'm not sure how.
I need all the data from Questionnaire, Booking, and Customers.
I think i have to join on the Booking has customers but i'm not sure.
At the moment i have something like this
SELECT *
FROM Booking,Questionaires,Customers
WHERE accepted = 0
JOIN ON Booking_idBooking = Customers_idCustomers
Can anyone help me out?
Thanks beforehand!
You could use inner join this way
SELECT * FROM Booking_idBooking as BB
INNER JOIN Booking as B on BB.Booking_idBooking = B.idBooking
INNER JOIN Customers as C on BB.Customers_idCustomers = C.idCustomers
INNER JOIN Questionaires as Q on Q.idQuestionaires = B.uestionaires_idQuestionaires
WHERE B.accepted = 0 ;
I would go about doing something like this, but you may need left joins depending one your circumstances.
select
*
from
customers c
inner join booking_has_customers bhs on
bhs.Customers_idCustomers = c.idCustomers
inner join booking b on
b.idBooking = booking_idBooking
inner join Questionaires q on
q.idQuestionaires = b.Questionairs_idQuestionairs
where
b.accepted = 0;
Just a note, you should really change your naming conventions.
For example booking is singular, yet customers is plural in your schema. They should be consistent. Also, something like idBooking and booking_idBooking is not great - maybe use id and booking_id. Anyway just suggestions.
You also might want to invest some time in learning how to write joins. Checkout w3schools for good examples.
SELECT b.*,q.*,c.*
FROM Booking AS b
JOIN Questionaries AS q ON q.idQuestionaries=b.Questionaries_idQuestionaries
JOIN Booking_has_Customers AS bhc ON bhc.Booking_idBooking=b.idBooking
JOIN Customers AS c ON c.idCustomers=bhs.Customers_idCustomers
WHERE b.accepted=0
But come on, change ID names into simple id and you'll have:
SELECT b.*,q.*,c.*
FROM Booking AS b
JOIN Questionaries AS q ON q.id=b.id
JOIN Booking_has_Customers AS bhc ON bhc.id=b.id
JOIN Customers AS c ON c.id=bhs.id
WHERE b.accepted=0
Why
Does this give incorrect results?
SELECT
people.name,
SUM(allorders.TOTAL),
SUM(allorders.DISCOUNT),
SUM(allorders.SERVICECHARGE),
SUM(payments.AMOUNT)
FROM
people
INNER JOIN
allorders ON allorders.CUSTOMER = people.ID
INNER JOIN
payments ON payments.CUSTOMER = people.ID
WHERE
people.ID = 7 AND allorders.VOIDED = 0 AND payments.VOIDED = 0
Gives: (the name), 1644000, 1100000, 50000, 1485000
If I do it two tables at a time (INNER JOIN people ON allorders.CUSTOMER = people.ID) in separate queries, I get the correct results. I don't don't even know where the numbers I get come from. Like:
SELECT
people.name,
SUM(allorders.TOTAL),
SUM(allorders.DISCOUNT),
SUM(allorders.SERVICECHARGE)
FROM
people
INNER JOIN
allorders ON allorders.CUSTOMER = people.ID
WHERE people.ID = 7 AND allorders.VOIDED = 0
Gives: (the name), 822000, 550000, 25000
SELECT
people.name,
SUM(payments.AMOUNT)
FROM
people
INNER JOIN payments ON payments.CUSTOMER = people.ID
WHERE people.ID = 7 AND payments.VOIDED = 0
Gives: (the name), 297000
It looks like it doubles, but I don't know why.
The odd thing is I have a similar query that does this sum correctly. I'll post it, but it's a bit complex. Here goes:
SELECT
t1.IDENTIFIER,
ifnull(t1.NAME,""),
t1.PRICE,
t1.GUESTS,
t1.STATUS,
ifnull(t1.NOTE,""),
t1.LINK,
ifnull(t1.EDITOR,""),
concat(t2.FIRSTNAME,"",t2.LASTNAME),
t2.ID,
t3.ID,
ifnull(t1.EMAIL,""),
ifnull(t3.PHONE,""),
ifnull(SUM(p1.AMOUNT),0),
ifnull(SUM(o1.DISCOUNT),0),
ifnull(SUM(o1.TOTAL),0),
ifnull(SUM(o1.SERVICECHARGE),0)
FROM
tables t1
INNER JOIN
people t2 ON t1.SELLER = t2.ID
INNER JOIN
people t3 ON t1.CUSTOMER = t3.ID
INNER JOIN
orderpaymentinfo ON orderpaymentinfo.TABLEID = t1.IDENTIFIER
INNER JOIN
payments p1 ON orderpaymentinfo.PAYMENTID = p1.PAYMENTID
INNER JOIN
allorders o1 ON o1.ORDERID = orderpaymentinfo.ORDERID
WHERE
p1.VOIDED = 0 AND o1.VOIDED = 0 AND t1.DATE = "2014-12-20"
GROUP BY t1.IDENTIFIER
The latter statement does the same join, only it uses an additional helper-table. I'm sorry it's a bit poorly formatted (I'm not great with SO's formatter), but if someone can tell me the difference between the logic in these two statements and how one can be completely wrong while the other right, I'd be very happy.
In response to answer:
Result 1:
Name - 5
Result 2:
Name - 2
Result 3:
Name - 10
Result 4 is truncated in phpMyAdmin - where would I get this easily?
Table structure for the three tables looks like:
SHOW create on the way.
Okay, so I am pretty sure you've a join condition that's basically exploding your result set into something like a Cartesian product. Here's what I think you should try
First, run the following and share the output:
SELECT p.name,COUNT(*)
FROM people as p
INNER JOIN allorders AS a
ON a.CUSTOMER = p.ID
WHERE p.ID = 7 AND a.VOIDED = 0
GROUP BY p.name
Then run
SELECT p.name,COUNT(*)
FROM people AS p
INNER JOIN payments AS pay
ON pay.CUSTOMER = p.ID
WHERE p.ID = 7 AND pay.VOIDED = 0
GROUP BY p.name
Then run
SELECT
p.name,
COUNT(*)
FROM
people as p
INNER JOIN
allorders as a ON a.CUSTOMER = p.ID
INNER JOIN
payments as pay ON pay.CUSTOMER = p.ID
WHERE
p.ID = 7 AND a.VOIDED = 0 AND pay.VOIDED = 0
GROUP BY p.name
Last run the following
SHOW CREATE TABLE people;
SHOW CREATE TABLE payments;
SHOW CREATE TABLE allorders;
The problem is that you don't have the correct understanding of your data. You need to give us a bit more info about the data and the relationships, and the output I've described here should help. Mine is not an answer. But if you run these queries and paste the output of them, you should be able to get an answer, either from me or someone else.
Based on the discussion and edits above, please try:
SELECT
p.name,
SUM(o.TOTAL),
SUM(o.DISCOUNT),
SUM(o.SERVICECHARGE),
MAX(pay.amt)
FROM
people as p
INNER JOIN
allorders AS o ON o.CUSTOMER = p.ID
INNER JOIN (SELECT customer,
SUM(amount) as amt
FROM payments
WHERE voided = 0 AND customer = 7
GROUP BY customer) AS pay
ON pay.customer = p.id
WHERE
p.ID = 7 AND o.VOIDED = 0
GROUP BY p.name
You could also do a subquery in your SELECT statement, but it's pretty obnoxious imo. You could also do min(pay.amt) or avg or even just leave the aggregate out altogether. The above should work... even though there are cleaner ways. I'm providing this answer so you can reason about why you were getting the unexpected result... actually optimizing your query is a different question that you can dive into later, once you've had a chance to look over this
Need some help with converting code from Join statement into Subquery.
I need to remove GROUP BY from it somehow, when converted into Subquery and don't know how.
Managed to put small portion of subquery at the end of the code, don't know how to do rest.
Need some help, thank you.
Here is the sample of the code: (need to convert into SQL Server syntax)
SELECT
b.Number, t.IDTyre, SUM(c.Price)
FROM Tyre AS t
INNER JOIN Bill AS b ON t.BillID = b.IDBill
INNER JOIN Customer AS c ON c.TyreID = t.IDTyre
GROUP BY b.Number, t.IDTyre
HAVING SUM(c.Price) < 3000 OR t.IDTyre NOT IN (SELECT c.TyreID FROM Customer AS c)
Check if the below query works:
SELECT
(Select b.Number From Bill AS b Where b.IDBill = t.BillID) as Number,
t.IDTyre as TyreID,
(Select SUM(c.Price) From Customer AS c Having SUM(c.Price) < 3000 OR t.IDTyre NOT IN (SELECT Distinct c.TyreID FROM Customer AS c) And c.TyreID = t.IDTyre) as Price
FROM Tyre AS t
Why are you trying to convert this to Sub Query?
JOINS are the best options while dealing with linking tables.
Also the "NOT IN" that you are trying to do at the end is also not good, you should use "NOT EXISTS". Change this to: OR NOT EXISTS (SELECT * FROM Customer AS c WHERE t.IDTyre=c.TyreID)