This question already has answers here:
Select statement to find duplicates on certain fields
(9 answers)
Closed 8 years ago.
Using the Chinook Test Database I wrote this SQL statement to show all the tracks ordered by two specific customers:
SELECT inv.BillingCity,cus.LastName,tra.Name
FROM invoice AS inv
JOIN customer AS cus ON inv.CustomerId=cus.CustomerId
JOIN invoiceline inl ON inv.InvoiceId=inl.InvoiceId
JOIN track tra ON tra.TrackId=inl.TrackId
WHERE cus.LastName IN ('Schneider','Schröder')
ORDER BY inv.BillingCity,cus.LastName,tra.Name
I see that there is a track that was ordered twice by one customer:
How would I write an SQL statement to find doubles like this, i.e. "return all tracks ordered multiple times by one customer"?
Try this:
SELECT cus.CustomerId,tra.Name,COUNT(cus.CustomerId) AS tot
FROM invoice AS inv
JOIN customer AS cus ON inv.CustomerId=cus.CustomerId
JOIN invoiceline inl ON inv.InvoiceId=inl.InvoiceId
JOIN track tra ON tra.TrackId=inl.TrackId
GROUP BY cus.CustomerId,tra.Name
HAVING tot > 1
Related
This question already has answers here:
How do I use alias in where clause? [duplicate]
(4 answers)
Closed 2 years ago.
Write a query to display hotel id, hotel name, and number of orders taken by hotels that have taken orders more than 5 times. Give an alias name for number of orders as 'NO_OF_ORDERS'.sort the result based on hotel id in ascending order.
Data Base Image
The Query I wrote:
select hotel_details.hotel_id, hotel_name, count(orders.hotel_id) as no_of_orders
from hotel_details join orders on hotel_details.hotel_id = orders.hotel_id
where no_of_orders > 5
group by orders.hotel_id order by no_of_orders;
Error I go:
unkown column 'number_of_orders' in 'where clause'
You need a HAVING clause, not a WHERE clause:
select
hd.hotel_id,
hd.hotel_name,
count(o.hotel_id) as no_of_orders
from hotel_details hd
inner join orders o on hd.hotel_id = o.hotel_id
group by
o.hotel_id
having
no_of_orders > 5
order by
no_of_orders;
The count of orders occurs during the GROUP BY portion of the query, at which point WHERE has already happened. So, assertions on anything from GROUP BY belong in a HAVING clause.
Overall what I'm trying to achieve is a query that shows the most ordered item from a customer in a database. To achieve this I've tried making a query showing how many times a customer has ordered an item, and now I am trying to create a sub-query in it using TOP1 to discern the most bought items.
With the SQL from the first query (looking weird because I made it with the Access automatic creator):
SELECT
Customers.CustomerFirstName,
Customers.CustomerLastName,
Products.ProductName,
COUNT(SalesQuantity.ProductCode) AS CountOfProductCode
FROM (Employees
INNER JOIN (Customers
INNER JOIN Sales
ON Customers.CustomerCode = Sales.CustomerCode)
ON Employees.EmployeeCode = Sales.EmployeeCode)
INNER JOIN (Products
INNER JOIN SalesQuantity
ON Products.ProductCode = SalesQuantity.ProductCode)
ON Sales.SalesCode = SalesQuantity.SalesCode
GROUP BY
Customers.CustomerFirstName,
Customers.CustomerLastName,
Products.ProductName
ORDER BY
COUNT(SalesQuantity.ProductCode) DESC;
I have tried putting in a subquery after FROM line:
(SELECT TOP1 CountOfProduct(s)
FROM (.....)
ORDER by Count(SalesQuantity.ProductCode) DESC)
I'm just not sure what to put in for the "from"-every other tutorial has the data from an already created table, however this is from a query that is being made at the same time. Just messing around I've put "FROM" and then listed every table, as well as
FROM Count(SalesQuantity.ProductCode)
just because I've seen that in the order by from the other code, and assume that the query is discerning from this count. Both tries have ended with an error in the syntax of the "FROM" line.
I'm new to SQL so sorry if it's blatantly obvious, but any help would be greatly appreciated.
Thanks
As I understand, you want the most purchased product for each customer.
So, begin by building aggregate query that counts product purchases by customer (appears to be done in the posted image). Including customer ID in the query would simplify the next step which is to build another query with TOP N nested query.
Part of what complicates this is unique record identifier is lost because of aggregation. Have to use other fields from the aggregate query to provide unique identifier. Consider:
SELECT * FROM Query1 WHERE CustomerID & ProductName IN
(SELECT TOP 1 CustomerID & ProductName FROM Query1 AS Dupe
WHERE Dupe.CustomerID = Query1.CustomerID
ORDER BY Dupe.CustomerID, Dupe.CountOfProductCode DESC);
Overall what I'm trying to achieve is a query that shows the most ordered item from a customer in a database.
This answers your question. It does not modify your query which is only tangentially related.
SELECT s.CustomerCode, sq.ProductCode, SUM(sq.quantity) as qty
FROM Sales as s INNER JOIN
SalesQuantity as sq
ON s.SalesCode = sq.SalesCode
GROUP BY s.CustomerCode, sq.ProductCode;
To get the most ordered items, you can use this twice:
SELECT s.CustomerCode, sq.ProductCode, SUM(sq.quantity) as qty
FROM Sales as s INNER JOIN
SalesQuantity as sq
ON s.SalesCode = sq.SalesCode
GROUP BY s.CustomerCode, sq.ProductCode
HAVING sq.ProductCode IN (SELECT TOP 1 sq2.ProductCode
FROM Sales as s2 INNER JOIN
SalesQuantity as sq2
ON s2.SalesCode = sq2.SalesCode
WHERE s2.CustomerCode = s.CustomerCode
GROUP BY sq2.ProductCode
);
In almost any other database, this would be simpler, because you would be able to use window functions.
This question already has answers here:
SQL JOIN and different types of JOINs
(6 answers)
Closed 7 years ago.
I have a table with multiple transaction types. Currently I'm only pulling the adjustments and payments, but I am needing to match the IDs of the types to their descriptions. For example, my transactions table has paytype_id and adjustment_id which range 1-100 for each. I have two other tables dbo.paytype and dbo.adjustments that have the distinct paytype_id and adjustment_id along with the pay_desc and adj_desc fields that describe what kind they are. Issue I'm running into is that any given transaction will only have a paytype_id or an adjustment_id but not both. So if I attempt to join one table, then the other I lose the NULL values of the secondary IDs
This query will pull the paytype_id descriptions but will remove any transactions with adjustment_id due to the payment_id being NULL for them.
SELECT
t.tran_num, t.resp_party_id, t.Total,
t.paytype_id, t.adjustment_id, t.clinic,
t.date_entered, p.pay_desc
FROM
adjpay_vw t
CROSS JOIN
paytype p
WHERE
(t.paytype_id = p.paytype_id AND t.clinic = p.clinic)
So I'm wondering how I can pull both the adj_desc from dbo.adjustments and the pay_desc from dbo.paytype
By having your join condition in the WHERE, it forces it to behave like an INNER JOIN. Instead of using the WHERE, add it to the JOIN condition and flip to a LEFT JOIN.
SELECT t.tran_num, t.resp_party_id, t.Total, t.paytype_id, t.adjustment_id, t.clinic, t.date_entered, p.pay_desc, adj.adj_desc, ISNULL(p.pay_desc,adj.adj_desc) [Description]
FROM adjpay_vw t
LEFT JOIN paytype p ON t.paytype_id=p.paytype_id AND t.clinic=p.clinic
LEFT JOIN dbo.adjustments adj ON adj.adjustment_id = t.adjustment_id
Also, since I wasn't sure your view contained the adjustment description, I've added a join for that and added both descriptions and a new columns that shows the description no matter if it was an adjustment or payment.
I'm just starting out with SQL, I have been playing around with simple select queries and grouping data, now I want to pull some actually useful data out of our database for analysis. The data is organized as follows:
Access 2010 Database
I didn't set it up, I know it isn't set up as it should be
I can't change data, only poll
-Customers are kept in one table
-Closed orders are kept in another table (each line item is listed with invoice #, date closed, Customer ID as well as other info)
-Archived closed orders table keep sales records that are a year + old (table is laid out exactly the same as Closed order table)
I want to start with a simple query, list all the customers from a certain branch and their past year totals. Here's what I have tried:
SELECT CUSTOMERS.Company, CUSTOMERS.[Ship City], (SELECT SUM (CLOSEDORDERS.Quant*CLOSEDORDERS.SellPrice) FROM CLOSEDORDERS WHERE CUSTOMERS.ID = CLOSEDORDERS.CustID) AS LifeTotal
FROM CUSTOMERS, CLOSEDORDERS
WHERE CUSTOMERS.Branch=33;
When I run the query, it asks me to enter a parameter value for CLOSEDORDERS.Quant. What am I doing wrong?
I think this is what you're looking for with an OUTER JOIN:
SELECT CUSTOMERS.Company,
CUSTOMERS.[Ship City],
SUM(CLOSEDORDERS.Quant*CLOSEDORDERS.SellPrice) AS LifeTotal
FROM CUSTOMERS
LEFT JOIN CLOSEDORDERS ON CUSTOMERS.ID = CLOSEDORDERS.CustID
WHERE CUSTOMERS.Branch=33
GROUP BY CUSTOMERS.Company,
CUSTOMERS.[Ship City]
If you only want to return matching results from both tables, then use a standard INNER JOIN instead of the LEFT JOIN.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
I'm having a hard time joining three separate tables in Oracle. I'm never joined three tables before so I'm not well versed. My theory is below:
SELECT customer_num WHEN customer_num IS 104 -198, order_num
FROM orders INNER JOIN items
ON order_num, stock_num
INNER JOIN stock
ON stock_num, description
Essentially, I'm trying to start with the ORDERS table and pull the customer number (customer_num) specifically customer number 104 -108 and the order_num from the orders table. Then attach the orders table to the Items table and attach the order_num and stock_num, and lastly attach the stock table and pull out the stock_num and description.
Your syntax is all over the place, and wouldn't work for a two-table join, or even querying a single table. Not sure where you got WHEN from, or the order of your clauses. Please review the SQL reference to see how to join and how to filter. Anyway...
You seem to want something like this:
SELECT o.customer_num, o.order_num, i.stock_num, s.description
FROM orders o
INNER JOIN items i ON i.order_num = o.order_num
INNER JOIN stock s ON s.stock_num = i.stock_num
WHERE o.customer_num BETWEEN 104 AND 198;
The WHERE clause is being applied to the orders table to restrict which customers' orders you get. I've assumed from your description that the orders and items tables have a common order_num column you can join on; and that the items and stock tables have a common stock_num column you can join on.
As OldProgrammer said, it would be helpful to include your table schemas in the question so assumptions don't need to be made, and showing sample data and expected output for that data would clarify what you're trying to do.
It should look something like this (based on the limited information about the schema)...
SELECT
O.CUSTOMER_NUM,
O.ORDER_NUM,
S.STOCK_NUM,
S.DESCRIPTION
FROM
ORDERS O,
ITEMS I,
STOCK S
WHERE
I.CUSTOMER_NUM >= 104
AND I.CUSTOMER_NUM <= 198
AND O.ORDER_NUM = I.ORDER_NUM
AND I.STOCK_NUM = S.STOCK_NUM
The syntax for a JOIN is:
TableExpression [ INNER ] JOIN TableExpression
{
ON booleanExpression | USING clause
}
The booleanExpression is what the tables will be linked by. So, in your example, something like this:
SELECT customer_num WHEN customer_num IS 104 -198, order_num
FROM orders INNER JOIN items
ON orders.<some_column> = items.<some_column>
INNER JOIN stock
ON items.<some_column> = stock.<some_column>