在SQL Server

时间:2018-01-07 12:18:26

标签: sql sql-server sql-server-2016

下游流表更新时是否有任何聪明的技巧来计算总数?我的意思是......想象你有3张桌子......

1)订单 - 键入订单ID

2)OrderLines - 键入订单ID和lineno,包含部件代码和数量

3)部件 - 键入Partid,带有成本和STATUS标志

现在我有一个SQL语句如下: SELECT o.orderid, sum(p.[cost] * l.[quantity]) as totalcost from orders o inner join orderslines l on o.orderid = l.orderid inner join parts p on p.partid = l.partid where p.statusflag = 'U' group by o.orderid

所以我正在寻找将零件状态更改为" U" (更新,或其他)。这有效,但只给我更新部分的总数。我想要委托订单的总数(所有行和部分),但仅适用于任何部分更新的订单。

现在我知道我可以创建一个where子句,其中orderno在列表中(并在链中做另一个大连接以获取订单号) - 但是想知道在SQL中是否有更简单的方法?

例如,想象一下,有12个表而不是3个表结构 - SQL会非常快速地变得非常复杂。我想知道是否有一个我错过的功能,一个KEYWORD的故事,说'#34;现在你有订单,只需重新计算这些订单的所有内容"

这是在SQL Server 2016上

由于

更新:根据要求,提供3个表和一些样本数据的测试集。我希望/希望只有orderid 3,值为15.51(2个产品2行,总共15.51,即使只有1个会更新),还有2号订单(总共11个) ,但不是订单1(因为订单1中的零件没有更新)......

CREATE TABLE [dbo].[Orders](
    [OrderId] [int] NOT NULL,
 CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED 
(
    [OrderId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =     OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[OrdersLines](
    [OrderId] [int] NOT NULL,
    [lineid] [int] NOT NULL,
    [PartId] [varchar](10) NULL,
    [quantity] [int] NULL,
    [statusflag] [varchar](1) NULL,
 CONSTRAINT [PK_OrdersLines] PRIMARY KEY CLUSTERED 
(
    [OrderId] ASC,
    [lineid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY =     OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Parts](
    [PartId] [varchar](10) NOT NULL,
    [cost] [float] NULL,
    [statusflag] [varchar](1) NULL,
 CONSTRAINT [PK_Parts] PRIMARY KEY CLUSTERED 
(
    [PartId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
INSERT [dbo].[Orders] ([OrderId], [StatusFlag]) VALUES (1, N'Y')
INSERT [dbo].[Orders] ([OrderId], [StatusFlag]) VALUES (2, N'Y')
INSERT [dbo].[Orders] ([OrderId], [StatusFlag]) VALUES (3, N'Y')
INSERT [dbo].[OrdersLines] ([OrderId], [lineid], [PartId], [quantity], [statusflag]) VALUES (1, 1, N'DOG', 1, N'Y')
INSERT [dbo].[OrdersLines] ([OrderId], [lineid], [PartId], [quantity], [statusflag]) VALUES (1, 2, N'CAT', 2, N'Y')
INSERT [dbo].[OrdersLines] ([OrderId], [lineid], [PartId], [quantity], [statusflag]) VALUES (2, 1, N'CAT', 3, N'Y')
INSERT [dbo].[OrdersLines] ([OrderId], [lineid], [PartId], [quantity], [statusflag]) VALUES (2, 2, N'FISH', 1, N'Y')
INSERT [dbo].[OrdersLines] ([OrderId], [lineid], [PartId], [quantity], [statusflag]) VALUES (2, 3, N'BEAR', 1, N'Y')
INSERT [dbo].[OrdersLines] ([OrderId], [lineid], [PartId], [quantity], [statusflag]) VALUES (3, 1, N'BEAR', 1, N'Y')
INSERT [dbo].[OrdersLines] ([OrderId], [lineid], [PartId], [quantity], [statusflag]) VALUES (3, 2, N'FRIMBLE', 1, N'Y')
INSERT [dbo].[Parts] ([PartId], [cost], [statusflag]) VALUES (N'BEAR',     4.4, N'U')
INSERT [dbo].[Parts] ([PartId], [cost], [statusflag]) VALUES (N'CAT', 1.1, N'Y')
INSERT [dbo].[Parts] ([PartId], [cost], [statusflag]) VALUES (N'DOG', 2.2, N'Y')
INSERT [dbo].[Parts] ([PartId], [cost], [statusflag]) VALUES (N'FISH', 3.3, N'Y')
INSERT [dbo].[Parts] ([PartId], [cost], [statusflag]) VALUES (N'FRIMBLE', 11.11, N'Y')

1 个答案:

答案 0 :(得分:0)

您可以使用

HAVING COUNT(CASE WHEN p.statusflag = 'U' THEN 'X' END) > 0

仅包含至少有一个部分的状态标志为U

的订单
SELECT o.orderid,
       sum(p.[cost] * l.[quantity]) AS totalcost
FROM   orders o
       INNER JOIN orderslines l
         ON o.orderid = l.orderid
       INNER JOIN parts p
         ON p.partid = l.partid
GROUP  BY o.orderid
HAVING COUNT(CASE WHEN p.statusflag = 'U' THEN 'X' END) > 0 

在您的示例数据中,这会返回订单2和3,因为它们都链接到设置了此标记的PartId BEAR