简体   繁体   English

MySQL计数与联接的情况

[英]Mysql count case with join

I'm trying to create a simple select statement and can't seem to get it right. 我正在尝试创建一个简单的select语句,似乎无法正确执行。 I have three tables. 我有三张桌子。 Here's the schema. 这是架构。

CREATE TABLE IF NOT EXISTS `SalesRepDealer` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `DealerId` varchar(20) NOT NULL,
  `DealerName` varchar(50) NOT NULL,
  `SalesRepId` varchar(30) NOT NULL,
  `SalesRepName` varchar(30) NOT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=629 ;

CREATE TABLE IF NOT EXISTS `PriorYearBoatOrders` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `DealerId` varchar(20) NOT NULL,
  `PriorYearSalesTotal` int(11) NOT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=2234 ;

CREATE TABLE IF NOT EXISTS `BoatOrdersCurrentYear` (
  `Id` int(11) NOT NULL AUTO_INCREMENT,
  `DealerId` varchar(40) COLLATE utf8_bin NOT NULL,
  `DealerName` varchar(50) COLLATE utf8_bin NOT NULL,
  `OrderNum` varchar(10) COLLATE utf8_bin NOT NULL,
  `BoatDescription` varchar(50) COLLATE utf8_bin NOT NULL,
  `SerialNum` varchar(50) COLLATE utf8_bin NOT NULL,
  `CompleteDate` varchar(15) COLLATE utf8_bin DEFAULT NULL,
  `ShipDate` varchar(15) COLLATE utf8_bin DEFAULT NULL,
  `ShipBy` varchar(15) COLLATE utf8_bin DEFAULT NULL,
  `Invoice` varchar(15) COLLATE utf8_bin DEFAULT NULL,
  `DocUnitPrice` int(11) DEFAULT NULL,
  `Customer` varchar(50) COLLATE utf8_bin DEFAULT NULL,
  `Po` varchar(30) COLLATE utf8_bin NOT NULL,
  PRIMARY KEY (`Id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=8192 ;

Here's my initial query that counts the open orders and shipped orders and filters the list by sales rep id. 这是我的初始查询,它计算未结订单和已发货订单,并按销售代表ID过滤列表。 This works perfectly, and gives me this result. 这完美地工作,并且给了我这个结果。

SELECT DealerId, DealerName, sum(case when ShipDate = '' then 1 else 0 end)  AS NumOpenOrders, sum(case when ShipDate != '' then 1 else 0 end)  AS NumShipped FROM BoatOrdersCurrentYear WHERE DealerId IN (SELECT DealerID FROM SalesRepDealer WHERE SalesRepId = 'bba') Group By DealerName

DealerId    DealerName  NumOpenOrders   NumShipped
BACA082017  Antler's Resort & Marina    0   5
CDGWAZ001   Got Water Marine    7   31
CDORHI014   HILLYERS SANTIAM MOTOR SPORTS   10  9
CDCAJM317   JOHNSON MARINE SUPPLIES INC 4   5
CDCABA0117  KDME, INC   4   0
CDIAMM015   Mark's Marine, Inc. 0   16
CDCANE001   Newport Pontoons, Inc.  0   1
CDIDPR043   Prestige Water Sports   15  4

Now I just want to add in the prior year totals. 现在,我只想添加上一年的总数。 I tried joins and other combinations of selects but the counts screw up and start getting wonky. 我尝试了联接和选择的其他组合,但是计数增加了,并开始变得笨拙。 I just need to take the Dealer Id from above query and match it up to the PriorYearBoatOrders and return PriorYearSalesTotal. 我只需要从上面的查询中获取Dealer ID,并将其匹配到PriorYearBoatOrders并返回PriorYearSalesTotal。 But here's the query I've been trying and the results. 但是这是我一直在尝试的查询和结果。

SELECT BoatOrdersCurrentYear.DealerId, BoatOrdersCurrentYear.DealerName, sum(case when BoatOrdersCurrentYear.ShipDate = '' then 1 else 0 end)  AS NumOpenOrders, sum(case when BoatOrdersCurrentYear.ShipDate != '' then 1 else 0 end)  AS NumShipped, PriorYearBoatOrders.PriorYearSalesTotal FROM BoatOrdersCurrentYear, PriorYearBoatOrders  WHERE BoatOrdersCurrentYear.DealerId IN (SELECT DealerId FROM SalesRepDealer WHERE SalesRepId = 'bba')Group By DealerName

DealerId    DealerName  NumOpenOrders   NumShipped  PriorYearSalesTotal
BACA082017  Antler's Resort & Marina    0   11165   5
CDGWAZ001   Got Water Marine    15631   69223   5
CDORHI014   HILLYERS SANTIAM MOTOR SPORTS   22330   20097   5
CDCAJM317   JOHNSON MARINE SUPPLIES INC 8932    11165   5
CDCABA0117  KDME, INC   8932    0   5
CDIAMM015   Mark's Marine, Inc. 0   35728   5
CDCANE001   Newport Pontoons, Inc.  0   2233    5
CDIDPR043   Prestige Water Sports   33495   8932    5

I'm not sure what's happening and why the totals are so far off. 我不确定发生了什么以及为什么总数如此之遥。 But i'm pretty new to query writing. 但是我对于查询写作还是很新的。 Any help is appreciated, sorry for the poorly formatted schema and queries. 感谢您提供任何帮助,对于格式和查询格式不正确的问题,我们深表歉意。

For every dealer, you're joining the data from this year with every dealer's data from last year - giving you a cross join; 对于每个经销商,您都将把今年的数据与去年的每个数据结合起来,从而获得交叉连接。 you need to add a join condition matching on DealerId. 您需要在DealerId上添加匹配的联接条件。

But you also need to start with a list of DealeIds, otherwise even with the condition on DealerId you'll be cross joining the orders. 但是,您还需要从DealeId列表开始,否则,即使有DealerId上的条件,您也会交叉加入订单。

SELECT
    d.DealerId,
    cy.DealerName,
    sum(case when cy.ShipDate = '' then 1 else 0 end) AS NumOpenOrders,
    sum(case when cy.ShipDate != '' then 1 else 0 end) AS NumShipped,
    py.PriorYearSalesTotal
FROM (SELECT distinct DealerId FROM SalesRepDealer WHERE SalesRepId = 'bba') d
JOIN BoatOrdersCurrentYear cy on cy.DealerId = d.DealerId
LEFT JOIN PriorYearBoatOrder py on py.DealerId = d.DealerId
group by 1,2

Note the use of: 注意以下用途:

  • aliases to improve readability 别名以提高可读性
  • "modern" (since 1992) join syntax “现代”(自1992年起)联接语法
  • subquery to generate the list of dealerIds 子查询以生成DealerId的列表
  • left join to return null is there were no sales last year 左联接返回null是否去年没有销售

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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