【问题标题】:Multiple Filter inside SELECT SQL StatementSELECT SQL 语句中的多个过滤器
【发布时间】:2017-05-13 02:02:59
【问题描述】:

我正在编写一个 SQL 语句来获取 Recordset 中的一些值,我将使用它来将结果传输到 Excel 中窗体上的 TextBoxes 中。涉及的表格有:

客户 -> 客户 ID、名字、姓氏、电话号码

发票 -> InvoiceId、CustomerId、CarModel、CarColor、CarPlate

维修 -> RepairId、InvoiceId、TypeOfRepair、PartOfCar、价格

服务 -> ServiceId、InvoiceId、日期、状态

当客户来到车库时,会创建一张与该客户相关联的发票。一张发票可以有多个维修。客户没有修车就走了,但发票在那里。如果客户决定修理汽车,则会创建一个服务,该服务以状态“正在处理...”开始。服务完成后,状态变为“Waiting for Check Out...”

我想使用 SQL 语句检索特定 InvoiceId 的以下值(列):

CarModel、Color、Plate、CustomerName (FirstName LastName)、PaintingTotalValue(其中“Painting”是“Type”列中的一种类型)、OtherTotalValue(此发票中所有其他类型维修的总价)、总价(总价,即画+其他)。

我编写了以下内容来获取值,但我不知道如何获取 PaintingTotalValue 和 OtherTotalVALue。

SELECT i.CarModel, i.Color, i.Plate, CONCAT(c.FirstName,' ',c.LastName) AS Name, FORMAT(SUM(r.Price),2) AS TotalPrice 
FROM Services AS s INNER JOIN Invoices AS i ON s.invoiceId=i.invoiceId
INNER JOIN Repairs AS r ON s.invoiceId=r.invoiceId 
INNER JOIN Customers AS c ON i.customerId=c.customerId
WHERE s.invoiceId = 15

【问题讨论】:

  • 您遇到错误了吗?它说什么?您的查询有一个聚合函数 (SUM) - GROUPed BY 的记录如何?未聚合的 SELECT 字段需要在 GROUP BY 子句中。
  • 我写的声明工作正常,问题是它只给了我总价。由于 Service 表上始终只有一个唯一 invoiceId,因此返回的 Recordset 仅包含一行,这就是我没有使用 GROUP BY 的原因...我试图在“SELECT”和“FROM”之间包含另外两个值(列),这将是与 invoiceId 和 type=Painting 匹配的价格总和,另一列是与 invoiceId 匹配且类型不是绘画的维修的 TotalPrice (SUM)(即所有其他类型)
  • 这是 MySQL 还是 SQL Server?因为两者的语法都不一样。
  • 我在 Excel (VBA) 上使用 ODBC 对象,与 MySQL 连接
  • 服装师是组装服装的人,即演员所穿的衣服——因此是购车市场的一小部分。也许你在想 customers

标签: mysql excel vba


【解决方案1】:

在您的SELECT 子句中使用CASE WHEN,以选择取决于类型的值:

SELECT
   ...
   CASE WHEN r.Type = 'Painting' THEN r.Price ELSE 0 END PaintWorkPrice,
   CASE WHEN r.Type <> 'Painting' THEN r.Price ELSE 0 END OtherWorkPrice,
FROM ...

这是一回事。

另一件事是您没有从Services 表中选择任何内容,这使您的查询比它需要的复杂得多。

如果您可以修改架构,请删除 ServiceId 主键字段,并改用 Services.InvoiceId 作为主键:这将自然地强制执行 1:1 关系。

FROM Repairs r
INNER JOIN Invoices i ON r.InvoiceId = i.InvoiceId
INNER JOIN Customers c ON i.CustomerId = c.CustomerId

您要聚合的数据细化为Repairs,因此您选择FROM,然后将外键移动到Customers

SELECT
    i.CarModel
   ,i.Color
   ,i.Plate
   ,CONCAT(c.FirstName,' ',c.LastName) Name
   ,CASE WHEN r.Type = 'Painting' THEN r.Price ELSE 0 END PaintWorkPrice
   ,CASE WHEN r.Type <> 'Painting' THEN r.Price ELSE 0 END OtherWorkPrice
   ,r.Price
FROM Repairs r
INNER JOIN Invoices i ON r.InvoiceId = i.InvoiceId
INNER JOIN Customers c ON i.CustomerId = c.CustomerId

这还没有汇总:每个维修、每个发票、每个有发票的客户都有一个记录。那部分是子查询。如果你有一个参数,那就是你使用它的地方。

WHERE i.InvoiceId = pInvoiceId

如果您只是对 ID 进行硬编码,那么您也可以这样做。

现在在上面的行中输入SELECT q.* FROM (,并在WHERE 子句下输入) q,然后将q.* 替换为您未聚合的字段 - 并聚合其他字段。结果应该是这样的:

SELECT
     q.CarModel
    ,q.Color
    ,q.Plate
    ,q.Name
    ,SUM(q.PaintWorkPrice) PaintAmount
    ,SUM(q.OtherWorkPrice) OtherAmount
    ,SUM(q.Price) TotalAmount
FROM (
    SELECT
        i.CarModel
       ,i.Color
       ,i.Plate
       ,CONCAT(c.FirstName,' ',c.LastName) Name
       ,CASE WHEN r.Type = 'Painting' THEN r.Price ELSE 0 END PaintWorkPrice
       ,CASE WHEN r.Type <> 'Painting' THEN r.Price ELSE 0 END OtherWorkPrice
       ,r.Price
    FROM Repairs r
    INNER JOIN Invoices i ON r.InvoiceId = i.InvoiceId
    INNER JOIN Customers c ON i.CustomerId = c.CustomerId
    WHERE i.InvoiceId = 15
) q
GROUP BY
     q.CarModel
    ,q.Color
    ,q.Plate
    ,q.Name

【讨论】:

  • 非常感谢 :) 我会修复一切,架构也一样。你真的帮了我很多!
  • 嗨@MathieuGuidon,对不起,我有最后一个问题,哈哈,你是如何创建插入问题中的表格设计的?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 2023-02-03
  • 2013-06-11
  • 2018-02-16
  • 2010-11-19
相关资源
最近更新 更多