【问题标题】:Query to retrieve info from one table and one extra col which is a condition from another table查询以从一个表和一个额外的 col 检索信息,这是另一个表的条件
【发布时间】:2016-01-25 16:28:55
【问题描述】:

我有一个工人表和一个关联的卡片表:

CREATE TABLE IF NOT EXISTS `workers` (
  `ID` varchar(20) NOT NULL,
  `companyID` int(11) NOT NULL,
  `FName` varchar(25) NOT NULL,
  `Sname` varchar(25) NOT NULL,
  `isAvailable` tinyint(4) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `workers`
 ADD PRIMARY KEY (`ID`), ADD KEY `cmp_idx` (`companyID`), ADD KEY `isAvailable_idx` (`isAvailable`);

我需要检索一份工人名单,每个工人都有一个指示他们的卡是否未获批准。

卡片表如下:

CREATE TABLE IF NOT EXISTS `cards2` (
`ID` int(11) NOT NULL,
  `Name` varchar(200) NOT NULL,
  `WorkerID` varchar(20) NOT NULL,
  `pic` varchar(200) NOT NULL,
  `expDate` bigint(20) NOT NULL,
  `reminderSent` tinyint(4) NOT NULL,
  `regNum` varchar(8) NOT NULL,
  `cardType` varchar(200) NOT NULL,
  `approvalStatus` tinyint(4) NOT NULL
) ENGINE=MyISAM AUTO_INCREMENT=95 DEFAULT CHARSET=latin1;

ALTER TABLE `cards2`
 ADD PRIMARY KEY (`ID`), ADD KEY `cardsWorkerID_idx` (`WorkerID`);

approvalStatus 可以是 2(尚未确定)、1(已批准)或 2(未批准) 因此,返回的指示符应仅在所有卡片均已获批准时为绿色 (1),如果任何卡片尚未获批准或未获批准,则应为红色 (0)。

检索工人的查询很简单:

SELECT distinct Workers.ID, FName, SName, companyID
FROM Workers WHERE companyID = ? and  
and isAvailable = 1
LIMIT ?, 10

在尝试取回卡片指示器时,我尝试了以下操作:

    SELECT Workers.ID, FName, SName, 
COUNT(CASE WHEN approvalStatus = 0 or approvalStatus = 2 THEN 1 ELSE 0 end) AS cardStatus 
FROM `workers` 
inner join cards2 ON Workers.ID = Cards2.WorkerID 
WHERE workers.companyID = 1

这只是返回一名工人

更新 如果用户没有关联的卡片,它还应该标记红色状态

【问题讨论】:

    标签: mysql sql count case


    【解决方案1】:

    您可以通过EXISTS 询问用户是否存在开放或未批准的卡:

    select id, fname, sname, companyid,
      case when exists 
      (
        select * 
        from cards2 c
        where c.workerid = w.id
        and c.approvalstatus in (0,2)
      ) then then 'red' else 'green' end as status
    from workers w 
    where companyid = ?
    and isavailable = 1;
    

    更新:这里是对没有卡 = 红色的附加要求的查询:

    select id, fname, sname, companyid,
      case when exists 
      (
        select * 
        from cards2 c
        where c.workerid = w.id
        and c.approvalstatus in (0,2)
      )
      or not exists 
      (
        select * 
        from cards2 c
        where c.workerid = w.id
      ) then then 'red' else 'green' end as status
    from workers w 
    where companyid = ?
    and isavailable = 1;
    

    这与聚合的状态和使用 MySQL 三布尔逻辑相同:

    select w.id, w.fname, w.sname, w.companyid,
      case when not c.bad then 'green' else 'red' end as status
    from 
    (
      select 
        workerid,
        max(case when approvalstatus in (0,2) then 1 else 0 end) as bad
      from cards2
      group by workerid
    ) c
    from workers w 
    where w.companyid = ? and  
    and w.isavailable = 1;
    

    【讨论】:

    • 我对查询还有一个额外的要求,我只是想到了,抱歉。如果用户没有上传相关的卡片,也应该标记为红色
    • 当然,最简单的方法是添加or not exists select * from cards2 c where c.workerid = w.id
    • 感谢您的回复,我尝试了您的最后一种方法并收到以下错误“MySQL 服务器版本,以便在 'group by workerid' 附近使用正确的语法”
    • 糟糕,缺少 FROM 子句。对不起。我现在已经更正了。
    • 是的,我发现了这一点,并认为这可能是问题所在,但是当我添加它时,我得到了错误:'MySQL 服务器版本,以便在'from workers w'附近使用正确的语法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多