【问题标题】:mysql query - select not finding a value [closed]mysql查询-选择未找到值[关闭]
【发布时间】:2011-12-30 08:39:51
【问题描述】:

有人可以帮我修改这个查询,以便我可以获得 outer_config.contractorsRef 值。目前它没有找到价值。我在下面的代码中突出显示了它。我已经用 count(*) 编写了查询,并在子查询中进行了选择,因为它的执行速度比 count(distinct) 快得多。

SELECT outer_config.contractorsRef AS cref, outer_config.contractorsRef AS contractorsRef, noworkers
FROM bis.request_config AS outer_config
LEFT JOIN (
    SELECT request_config.contractorsRef, (
        SELECT COUNT( * ) subcount
        FROM (
            SELECT DISTINCT subcontractorRef
            FROM bis.Request
            INNER JOIN bis.request_config ON request_config.RIDGROUP = request.RIDGROUP
            AND currenttaxyear =2011
            AND weekno =33
            AND contractorsRef=outer_config.contractorsRef ############ERROR HERE###########
            GROUP BY contractorsRef
        )x
    )noworkers
    FROM bis.Request
    INNER JOIN bis.request_config ON request_config.RIDGROUP = request.RIDGROUP
    AND currenttaxyear =2011
    AND weekno =33
)T1 ON T1.contractorsRef = outer_config.contractorsRef
WHERE currenttaxyear =2011
AND weekno =33
AND outer_config.contractorsRef <>132
GROUP BY outer_config.contractorsRef

表定义

-

CREATE TABLE request_config (
  RIDGROUP int(11) NOT NULL AUTO_INCREMENT,
  sessionstart text NOT NULL,
  EmployeeID int(11) NOT NULL,
  closedrequest tinyint(1) NOT NULL,
  contractorsRef int(11) NOT NULL DEFAULT '0',
  timesheetDateSubmited text,
  requesttotal int(11) NOT NULL DEFAULT '0',
  imported int(11) NOT NULL DEFAULT '0',
  dateref text,
  onlinespreadsheet int(11) NOT NULL DEFAULT '0',
  marginamt double NOT NULL DEFAULT '0',
  grossamt double NOT NULL DEFAULT '0',
  feespaidbyclient int(11) NOT NULL DEFAULT '0',
  currenttaxyear int(11) NOT NULL DEFAULT '0',
  weekno int(11) NOT NULL DEFAULT '0',
  subdedamt double NOT NULL DEFAULT '0',
  timesheetfrequency int(11) NOT NULL DEFAULT '0',
  onlinesubmission int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (RIDGROUP),
  KEY contractorsRef_2 (contractorsRef,currenttaxyear,weekno)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;

CREATE TABLE request (
  RID int(11) NOT NULL,
  RIDGROUP int(11) NOT NULL,
  EmployeeID int(11) NOT NULL,
  date_requested text NOT NULL,
  hours double NOT NULL,
  rate double NOT NULL,
  agencydeduction double NOT NULL,
  otherpay double NOT NULL,
  totaltimesheet double NOT NULL,
  subcontractorRef text NOT NULL,
  candidatename text NOT NULL,
  candidatename_sys text NOT NULL,
  validated tinyint(1) NOT NULL DEFAULT '0',
  requestclosed tinyint(1) NOT NULL DEFAULT '0',
  paytypeID int(11) NOT NULL DEFAULT '0',
  retrieved int(11) NOT NULL DEFAULT '0',
  KEY RID (RID),
  KEY RIDGROUP (RIDGROUP),
  KEY subcontractorRef (subcontractorRef(20))
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

--

CREATE TABLE contractors (
  contractorsRef int(11) NOT NULL AUTO_INCREMENT,
  contractorsName text,
  contractName text,
  TELEPHONE text,
  MOBILE text,
  FAX text,
  contractorsAddress1 text,
  contractorsAddress2 text,
  contractorsAddress3 text,
  contractorsAddress4 text,
  contractorsAddress5 text,
  contractorsAddresspostcode text,
  emailaddress text,
  websiteadd text,
  Contractsent int(11) DEFAULT '0',
  Contractreceived int(11) DEFAULT '0',
  officeno int(11) DEFAULT '0',
  clientID text,
  jobtype int(11) DEFAULT '0',
  weeknopaymentfilereceived int(11) DEFAULT '0',
  timetogenerateemail text,
  daytogenerateemail text,
  weeknoremindersent int(11) DEFAULT '0',
  weeknoremindersent_O2 int(11) DEFAULT '0',
  disabledreminder int(11) DEFAULT '0',
  active int(11) NOT NULL DEFAULT '0',
  createdbyEmployeeID int(11) NOT NULL DEFAULT '0',
  marginagreed double NOT NULL DEFAULT '0',
  rebateagreed double NOT NULL DEFAULT '0',
  marketing int(11) NOT NULL DEFAULT '0',
  ARDENTORO2 int(11) NOT NULL DEFAULT '0',
  www text,
  clientID2 text,
  attentionneeded int(11) NOT NULL DEFAULT '0',
  UNREFCOUNTER int(11) NOT NULL DEFAULT '0',
  feespaidbyclient int(11) NOT NULL DEFAULT '0',
  request_manual_entry int(11) NOT NULL DEFAULT '0',
  payupon int(11) NOT NULL DEFAULT '0',
  weektostartreminder text,
  reminder_duration int(11) NOT NULL DEFAULT '0',
  dayofweekpaymentexpected int(11) NOT NULL DEFAULT '0',
  Correspondence text,
  timesheetfrequency int(11) NOT NULL DEFAULT '0',
  atnc int(11) NOT NULL DEFAULT '0',
  nextts_expected int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (contractorsRef),
  KEY clientID (clientID(8))
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

【问题讨论】:

  • 请提供您的表定义。

标签: mysql select count distinct


【解决方案1】:

看来您正在尝试获取以下内容... 每个承包商的名单。从每个承包商那里,他们正在与多少不同的分包商合作。由此,承包商的所有分包商的工人总数。如果这是正确的,那么下面的查询可能更符合您的需求。

第一个“来自”查询只是获取承包商+分包商的合格条件和按承包商+分包商分组的计数。

从该结果中,获取承包商的查询,然后获取分包商的 COUNT 个,然后对分包商的工人计数求和。

在 (CurrentTaxYear, WeekNo, ContractorsRef) 上的 Request_Config 表上创建一个索引。您希望索引代表查找共同组的最小粒度。在这种情况下,任一纳税年度/周(而不是周/纳税年度,否则将在给定周内交错所有年份,因此有更多记录)。通过按年 + 周进行索引,您将只能获得特定于时间段的数据,而不会像刚才描述的那样交错。在该集合中,跳过您不想要的一个承包商参考很容易。

此外,为了帮助分组(内部查询),您可能希望 RIDGROUP 和 SubContractorRef(20) 上的请求表上的另一个索引来帮助保持它们在子结果集中预先排序。

在更好地审查您的表结构后,我还调整了内部查询,以基于请求配置表 FIRST 和 JOIN 到请求表第二个进行查询。 “WHERE”子句直接应用于配置请求表(通过索引优化)。

SELECT
      PreQuery.ContractorsRef,
      COUNT(*) as SubContractors,
      SUM( PreQuery.subCount  ) as SubContRequests
   from 
      ( SELECT 
              RCNF.contractorsRef,
              REQ.SubContractorRef,
              COUNT( * ) subcount
           FROM
              bis.request_config RCNF
                 JOIN bis.Request REQ
                    ON request.RIDGROUP = request_config.RIDGROUP
           WHERE
                    RCNF.currenttaxyear = 2011
                AND RCNF.weekno = 33
                AND RCNF.ContractorsRef <> 132
           GROUP BY
              RCNF.contractorsRef,
              REQ.SubContractorRef ) PreQuery
   group by
      PreQuery.ContractorsRef

-- 再次澄清结果--

根据您的上一条评论...被重复计算 假设您有以下记录。

Request_Config
RIDGroup  ContractorsRef  
1         111     Even by this example, if a contractor ref can be 
2         222     duplicated as a different "RIDGroup" and would appear
3         333     two times.  This COULD / WOULD cause duplications when
4         111     joining to the Request table on just the ContractorsRef column


Request file
RID  RIDGroup  SubContractorRef
52   1         SubA
53   2         SubB
54   3         SubC
55   4         SubA
56   1         SubA  (second work/hours/pay request from same job?)
57   4         SubA  (second request for second job under same contractor)?
58   2         SubD
59   2         SubE
60   1         SubF

The INNER part of the query would return
ContractorsRef  SubContractorRef   Count
111             SubA               4  (as derived from 
                                          RIDGroup 1 having 2 entries and 
                                          RIDGroup 4 having 2 entries
111             SubF               1  (since only against RIDGroup #1, (not #4)
222             SubB               1
222             SubD               1
222             SubE               1
333             SubC               1

如您所见,“SubA”仍然只针对 ContractorsRef 111 出现一次,并显示该子的 4 个唯一请求条目...因此,仅按 ContractorsRef 分组的 OUTER 查询将具有

ContractorsRef  SubContractors  SubContRequests
111             2               5
222             2               2
333             1               1

(我更改了查询列的最终名称以正确反映总计的上下文)。

【讨论】:

  • 这行得通,但查询花费的时间比我预期的要长。还有其他选择吗,谢谢?
  • @user984314,请参阅修订后的答案和索引 cmets。这应该对性能有很大帮助。
  • 对不起,伙计,结果并没有给我独特的 subcontworkers。 1 名工作人员可能在 RIDGROUP 下拥有超过 1 条记录。我想提出一种更快的方法来计算记录,而不是 count(distinct) 方法。有任何想法吗?非常感谢您的宝贵时间!
  • @user984314,所以...您是说分包商可以为多个承包商工作...而您只想计算该分包商一次?不管他们为多少承包商工作?如果是这样,我会调整查询以仅将分包商与第一个承包商相关联,这样他们就不会被重复计算......这是否是您正在寻找的更多内容?
  • 一个分包商可以为 1 个承包商正常工作。但肯定会有 1 个承包商在其付款中获得超过 1 条工资的情况。因此,客户可能会为同一个分包商发送超过 1 x 200 和 1 x 100。但是这个报告应该显示的是计数 1 而不是计数 2(这就是它正在做的事情)
猜你喜欢
  • 2012-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-15
  • 2018-04-30
  • 1970-01-01
  • 2020-07-31
  • 2011-09-18
相关资源
最近更新 更多