2

我在弄清楚以下 mysql 查询时遇到了一些麻烦。

这是一种时间跟踪,用户根据他们所做的任务有一定的费率。而且我需要有一个摘要,以便我知道在周末向用户支付什么费用。

-----------tSessions---------------------------
|id      |userid  |typeid  |session_length_min
-----------------------------------------------
|1       |1       |1       |30
-----------------------------------------------
|2       |1       |1       |45
-----------------------------------------------
|3       |1       |2       |(null)
-----------------------------------------------
|4       |2       |2       |(null)
-----------------------------------------------


-----------tUsers-----------------------------------------------------------------------------------
|id      |name  |rate_cleaning_30_min   |rate_cleaning_45_min   |rate_kitchenwork  |rate_dogwalking
----------------------------------------------------------------------------------------------------
|1       |Tom   |30                     |50                     |40                |20
----------------------------------------------------------------------------------------------------
|2       |Joe   |35                     |60                     |45                |20
----------------------------------------------------------------------------------------------------
|3       |Dave  |40                     |60                     |30                |10
----------------------------------------------------------------------------------------------------


-----------tTypes----------------
|id      |name
---------------------------------
|1       |Cleaning
---------------------------------
|2       |Kitchenwork
---------------------------------
|3       |Dogwalking
---------------------------------


============== Required Result ====================
|username   |sessioncount   |amount_to_pay
---------------------------------------------------
|Tom        |2              |120
---------------------------------------------------
|Joe        |1              |45
---------------------------------------------------

如果我的方法不太成功,则下面的查询是一个:

SELECT
tSessions.id,
tSessions.userid,
tSessions.typeid,
tSessions.session_length_min,
SUM(tUsers.rate_cleaning_30_min) AS rate_cleaning_30_min_sum,
SUM(tUsers.rate_cleaning_45_min) AS rate_cleaning_45_min_sum,
SUM(tUsers.rate_kitchenwork) AS rate_kitchenwork,
SUM(tUsers.rate_dogwalking) AS rate_dogwalking,
Count(*) AS sessioncount,
FROM
tSessions
INNER JOIN tUsers ON tSessions.userid = tUsers.id
WHERE WEEKOFYEAR(FROM_UNIXTIME(datetime))=WEEKOFYEAR(NOW())-1
GROUP BY
tSessions.userid,
tSessions.typeid
4

3 回答 3

2

这是一个SQLFiddle 示例

select tUsers.Name,
count(*) as sessioncount,
sum(
if(typeid=1,
          if(session_length_min<=30,rate_cleaning_30_min,
            rate_cleaning_45_min) 
          ,0)
+
  if(typeid=2,rate_kitchenwork,0)
+
 if(typeid=3,rate_dogwalking,0)
) as amount_to_pay

from
tSessions
left join tUsers on tSessions.userid=tUsers.id
group by tUsers.Name

但是你的基础方案不好。如果您需要添加或删除任务类型怎么办。您应该将 tUsers 和 Task 的价格分开。只需添加新表 tRates 并修改 tTypes:

    -----------tTypes----------------
    |id      |name
    ---------------------------------
    |1       |Cleaning 30 min
    ---------------------------------
    |2       |Kitchenwork
    ---------------------------------
    |3       |Dogwalking
    ---------------------------------
    |4       |Cleaning 45 min
    ---------------------------------

-----------tSessions--------
|id      |userid  |typeid  |
----------------------------
|1       |1       |1       |
----------------------------
|2       |1       |4       |
----------------------------
|3       |1       |2       |
----------------------------
|4       |2       |2       |
----------------------------


-----------tUsers-----------------
|id      |name  |
-----------------
|1       |Tom   |
-----------------
|2       |Joe   |
-----------------
|3       |Dave  |
-----------------


and add tRates table with USER<->TASKS rates:


-----------tRates--------
|id      |userid  |typeid  | rate   |
---------------------------------------
|1       |1       |1       |30      |
--------------------------------------
|2       |1       |2       |40      |
--------------------------------------
|3       |1       |3       |20      |
--------------------------------------
|4       |1       |4       |50      |
--------------------------------------
|5       |2       |1       |35      |
--------------------------------------
|6       |2       |2       |45      |
--------------------------------------
|7       |2       |3       |20      |
--------------------------------------
|8       |2       |4       |60      |
--------------------------------------
|9       |3       |1       |40      |
--------------------------------------
|10      |3       |2       |30      |
--------------------------------------
|11      |3       |3       |10      |
--------------------------------------
|12      |3       |4       |60      |
--------------------------------------
于 2012-09-11T10:51:48.090 回答
1


我相信这里的问题是您的数据没有正确写入。
首先,您需要一个费率表:

创建表`trates`(
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `type_id` int(11) NOT NULL,
  `rate` int(11) 默认为空,
  主键(`id`),
  唯一键 `unique` (`user_id`,`type_id`)
)

用每人正确的费率填充表格:

INSERT INTO trates VALUES (NULL,(SELECT id FROM tusers WHERE NAME = 'Tom'),(SELECT id FROM ttypes WHERE NAME = 'Cleaning'),30);
 INSERT INTO trates VALUES (NULL,(SELECT id FROM tusers WHERE NAME = 'Tom'),(SELECT id FROM ttypes WHERE NAME = 'Kitchenwork'),40);
 INSERT INTO trates VALUES (NULL,(SELECT id FROM tusers WHERE NAME = 'Tom'),(SELECT id FROM ttypes WHERE NAME = 'Dogwalking'),20);

 INSERT INTO trates VALUES (NULL,(SELECT id FROM tusers WHERE NAME = 'Joe'),(SELECT id FROM ttypes WHERE NAME = 'Cleaning'),35);
 INSERT INTO trates VALUES (NULL,(SELECT id FROM tusers WHERE NAME = 'Joe'),(SELECT id FROM ttypes WHERE NAME = 'Kitchenwork'),45);
 INSERT INTO trates VALUES (NULL,(SELECT id FROM tusers WHERE NAME = 'Joe'),(SELECT id FROM ttypes WHERE NAME = 'Dogwalking'),20);

 INSERT INTO trates VALUES (NULL,(SELECT id FROM tusers WHERE NAME = 'Dave'),(SELECT id FROM ttypes WHERE NAME = 'Cleaning'),40);
 INSERT INTO trates VALUES (NULL,(SELECT id FROM tusers WHERE NAME = 'Dave'),(SELECT id FROM ttypes WHERE NAME = 'Kitchenwork'),30);
 INSERT INTO trates VALUES (NULL,(SELECT id FROM tusers WHERE NAME = 'Dave'),(SELECT id FROM ttypes WHERE NAME = 'Dogwalking'),10);


接下来,这里的费率类型有问题,因为您指的是2个组合数据-工作类型+工作时间
清洗30分钟
清洗45分钟
是不是意味着只能在这两个中进行清洗?
其他任务可以是 30 和 45 分钟吗?
费率通常是每小时,这意味着如果费率是每小时 20 美元并且一个人工作 120 分钟,则应该是 TimeSpent/60*PayPerHourRate (120/60*20)

如果始终是 30 和 45 分钟,我建议添加对您的类型表的价值:

身份证名称
1 清洁30m
2 厨房工作
3 遛狗
4 清洁45m


从这一点来看,总结数据很容易:)

于 2012-09-11T10:56:32.317 回答
0

您的表格设计存在一些问题,即...如果您在“tTypes”表格中再添加一行,那么您必须在“tUsers”表格中添加一列。那不是一个好的设计。

我稍微修改了您的“tUsers”表并添加了一个名为“trates”的表

新的 tUses 表结构如下所示

在此处输入图像描述

新的 'trates' 表会像

在此处输入图像描述

下面给出了创建新“汇率”表的脚本

CREATE TABLE `trates` (
    `id` INT(10) NOT NULL AUTO_INCREMENT,
    `typeid` INT(11) NOT NULL DEFAULT '0',
    `userid` INT(11) NOT NULL DEFAULT '0',
    `rate` INT(11) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=13;

下面给出了将数据插入“trats”表的脚本

INSERT INTO `trates` (`id`, `typeid`, `userid`, `rate`) VALUES
    (1, 1, 1, 30),
    (2, 2, 1, 50),
    (3, 3, 1, 40),
    (4, 4, 1, 20),
    (5, 1, 2, 35),
    (6, 2, 2, 60),
    (7, 3, 2, 45),
    (8, 4, 2, 20),
    (9, 1, 3, 40),
    (10, 2, 3, 60),
    (11, 3, 3, 30),
    (12, 3, 3, 10);

这种设计的优点是,如果您在“tTypes”表中再添加一种类型,那么您只需在“trates”表中插入一行,而不是在旧表中创建一列。

我使用了相同的 'tSessions' 和 'tTypes' 表..

创建我的新表后,您可以使用以下查询来获得所需的结果

select usr.name, (select  count(distinct userid,typeid) 
 from tsessions tsess where
 tsess.userid=usr.id ) as 'sessioncount', sum(rate) as 'amount_to_pay'
 from tusers usr,trates rts,tsessions sess1 where rts.userid=usr.id
  and rts.typeid=sess1.typeid and sess1.userid=usr.id  
group by usr.name 

在此处输入图像描述

汤姆的 sessioncount 是 3,因为我在 'tTypes' 表中为 'cleaning_30_min' 和 'cleaning_45_min' 添加了单独的行。在这种情况下,我认为 3 是正确的会话数

于 2012-09-13T05:23:37.743 回答