简体   繁体   中英

My question is about SQL, using a TOP function inside a sub-query in MS Access

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM