【问题标题】:Query That Returns First Results from Subquery从子查询返回第一个结果的查询
【发布时间】:2013-08-24 13:25:38
【问题描述】:

我正在尝试创建一个从结果集中的子查询返回结果的查询。

这是我正在使用的表格:

Orders       OrderDetails     
-------      -----------     
orderId      orderDetailId         
(other data) orderId
             productName     

我想获取每个订单的前两个订单详细信息(大多数订单只有一个或两个详细信息)。以下是所需结果集的示例:

orderId   (other order data)   productName1   productName2
-------   ------------------   ------------   ------------
1         (other order data)   apple          grape
2         (other order data)   orange         banana
3         (other order data)   apple          orange

这是我迄今为止尝试过的:

SELECT o.orderid, 
       Max(CASE WHEN detail = 1 THEN oi.productname END) AS ProductName1, 
       Max(CASE WHEN detail = 2 THEN oi.productname END) AS ProductName2 
FROM orders AS o 
    OUTER apply (SELECT TOP 2 oi.*, 
                     Row_number() OVER (ORDER BY orderdetailid) AS detail 
                FROM orderdetails AS oi 
                WHERE oi.orderid = o.orderid) AS oi 
GROUP BY o.orderid 

我在托管电子商务解决方案的自定义报告模块中执行此操作,并收到以下无用的语法错误:SQL 错误:'(' 附近的语法不正确。

很遗憾,我不知道我使用的是什么版本的 SQL Server。客户支持一无所知,选择@@Version 不起作用。

请注意,即使错误消息按名称引用该函数,似乎也无法正确支持 row_number() 函数。

感谢您的帮助!

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    这是一个不使用交叉应用的替代方案。您的排名是正确的,但我按顺序添加了分区。

    SELECT 
    *
    FROM
    (
        SELECT
            o.orderid,
            ProductName=oi.productcode, 
            RowNumber=ROW_NUMBER() OVER (PARTITION BY o.orderid ORDER BY oi.orderdetailid) 
        FROM
            orders as o
            INNER JOIN orderdetailid oi ON oi.orderid=o.orderid
    )AS X
    WHERE
        RowNumber=1
    

    不使用 row_number

    SELECT
        orderdetails.*
        Q1.* 
    FROM
    (   
        SELECT 
            o.*, 
            FirstOrderDetailID=(SELECT MIN(orderdetails.orderdetailsid) FROM orderdetails WHERE orderid=o.orderid)
        FROM
            orders o    
    )AS Q1     
    LEFT OUTER JOIN orderdetails oi ON oi.orderdetailsid=Q1.FirstOrderDetailID     
    

    【讨论】:

    • 感谢您的快速回复。我修正了一个小错字来内部连接表 orderdetails 而不是 orderdetailid。之后它给了我语法错误:SQL错误:'orderid'附近的语法不正确。只是为了笑,我删除了'Partition by o.orderid',它给了我语法错误:SQL错误:'('附近的语法不正确。有什么想法吗?
    • 也许您正在查询的数据库是
    • 我也在想同样的事情,但是当我从 row_number() 函数中删除 Order By 时,我得到这个:排名函数“ROW_NUMBER”必须有一个 ORDER BY 子句。
    • 嗯...不知道朋友。
    • 我担心你会这么说,但我真的很感激你的洞察力。知道如何在不使用 row_number() 函数的情况下执行此操作吗?
    【解决方案2】:

    如果您只是选择orderid和产品,则根本不需要加入:

    select orderid, productcode
    from (SELECT oi.orderid, oi.productcode,
                 row_number() over (partition by oi.orderid order by oi.orderdetailid) as seqnum
          FROM orderdetails oi
         ) oi
    where seqnum = 1;
    

    如果row_number() 不起作用,这可能无法解决问题,但它简化了查询。您也可以使用min() 方法来做到这一点:

    select orderid, productcode
    from orderdetails oi
    where oi.orderdetailid in (select min(orderdetailid) from orderdetails group by orderid);
    

    【讨论】:

    • 抱歉,我应该明确表示我需要 Orders 表中的其他数据。我编辑了问题以反映这一点。我还希望获得两个订单详细信息,而不仅仅是一个。
    猜你喜欢
    • 1970-01-01
    • 2018-12-18
    • 1970-01-01
    • 2015-03-16
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多