Sql group by和join问题

时间:2016-05-09 13:24:50

标签: sql sql-server database sql-server-2008 join

也许只是因为我本周末睡眠不足,但似乎无法修复它。 我有这些表:

  • 产品(PK产品与fk categoryid)
  • ShippedProducts(带有FK ShipmentID和fk productid的PK ShippedProductsID)
  • 货件(带有FK InvoiceID的PK ShipmentID)
  • 发票(带有FK CustomerID的PK InvoiceID)
  • 客户(使用FK CountryId的PK CustomerID)
  • 国家/地区(PK CountryID)
抱歉,没有其他方法可以解释架构。如果我能更好地概述数据结构,请告诉我。

这是我的SQL(数据库是Microsoft SQL server 2008)

SELECT  countries.countryid, 
        countryname, 
        isnull(round(sum(InvoiceTotal), 2),0) as TotalInvoice,
        count(invoices.invoiceid) as nrOfInvoices,
        count(shipments.shipmentid) as nrOfShipments
FROM    INVOICES
inner join customers on invoices.CustomerID = customers.customerid
inner join countries on customers.CountryID = COUNTRIES.CountryID 
inner join shipments on shipments.invoiceid = invoices.invoiceid
inner join ShippedProducts on ShippedProducts.ShipmentID = shipments.ShipmentID
group by countryname, COUNTRIES.CountryID, CurrencyName, CURRENCIES.CurrencyID

如果我注释掉最后一个内部联接(带有发货产品),我会得到正确数量的发票等,但是当我加入发货产品时,计数不会计算invoiceid,但不知道货物的数量是多少。 如果我向该组添加更多内容,它将不再按国家/地区分组,并且每个发票和发货等都有一行。 我不知何故在星期一不能看到我的错误。也许我只需要更多的咖啡。

2 个答案:

答案 0 :(得分:0)

看来你的问题是加入一对多的关系。

我认为您应该将ShippedProducts.ShipmentProductsID的计数放入select语句的子选择中。这样的事也许......

select countries.countryid, 
    countryname, 
    isnull(round(sum(InvoiceTotal), 2),0) as totalInvoice,
    count(invoices.invoiceid) as nrOfInvoices,
    count(shipments.shipmentid) as nrOfShipments
    (select count shipmentproductsid from shipmentproducts where shipmentproducts.shipmentid = shipments.shipmentID)  as totalProd 
from invoices
    inner join customers on invoices.customerid = customers.customerid
    inner join countries on customers.countryid = countries.countryid
    inner join shipments on shipments.invoiceid = invoices.invoiceid    
group by countryname, countries.countryid , currencyname, currencies.currencyid

答案 1 :(得分:0)

您应该能够使用窗口函数来执行此操作而无需分组。喜欢这个

SELECT
  countries.countryid, 
  countryname, 
  isnull(round(sum(InvoiceTotal) over (partition by invoice.invoiceID), 2),0) 
     as TotalInvoice,
  count(invoices.invoiceid) 
     over (partition by countries.countryid) as nrOfInvoicesPerCountry,
  count(shipments.shipmentid) over (partition by coutries.countryid) 
     as nrOfShipments
FROM INVOICES
inner join customers on invoices.CustomerID = customers.customerid
inner join countries on customers.CountryID = COUNTRIES.CountryID 
inner join shipments on shipments.invoiceid = invoices.invoiceid
inner join ShippedProducts on ShippedProducts.ShipmentID = shipments.ShipmentID