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
---------------------------------------------------

以下のクエリは、あまり成功していないアプローチの場合の 1 つです。

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


ここでの問題は、データが正しく書き込まれていないことだと思います。
まず、レート テーブルが必要です。

CREATE TABLE `trates` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `type_id` int(11) NOT NULL,
  `rate` int(11) DEFAULT NULL,
  主キー (`id`)、
  UNIQUE KEY `unique` (`user_id`,`type_id`)
)

1 人あたりの正しい料金を表に入力します。

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 = 'キッチンワーク'),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 = 'キッチンワーク'),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 = 'キッチンワーク'),30);
 INSERT INTO trates VALUES (NULL,(SELECT id FROM tusers WHERE NAME = 'Dave'),(SELECT id FROM ttypes WHERE NAME = 'Dogwalking'),10);


次に料金タイプの問題ですが、作業タイプ+作業時間の2つのデータを合わせたものなので、
清掃30分
清掃45分
ということは、清掃はこの2つでしかできないということでしょうか?
他のタスクを 30 分と 45 分にすることはできますか?
料金は通常 1 時間あたりです。つまり、料金が 1 時間あたり 20 ドルで、1 人が 120 分働いた場合、TimeSpent/60*PayPerHourRate (120/60*20)

になります。常に 30 分と 45 分である場合は、あなたのタイプテーブルへの値:

ID名
1 クリーニング30m
2 キッチンワーク
3 ドッグウォーク
4 クリーニング45m


この時点から、データの合計は簡単です:)

于 2012-09-11T10:56:32.317 に答える
0

テーブルの設計に問題があります。つまり、「tTypes」テーブルに行をもう 1 つ追加すると、「tUsers」テーブルに列を 1 つ追加する必要があります。それは良い設計ではありません。

「tUsers」テーブルを少し変更し、「trates」という名前のテーブルをもう 1 つ追加しました

新しい tUses テーブル構造を以下に示します

ここに画像の説明を入力

新しい「trates」テーブルは次のようになります

ここに画像の説明を入力

新しい「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;

データを「trates」テーブルに挿入するスクリプトを以下に示します

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」テーブルにもう 1 つのタイプを追加する場合、古いテーブルに 1 つの列を作成する代わりに、「trates」テーブルに 1 つの行を挿入するだけでよいことです。

同じ「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 

ここに画像の説明を入力

'tTypes' テーブルに 'cleaning_30_min' と 'cleaning_45_min' に別々の行を追加するため、Tom の sessioncount は 3 です。この場合、3 が正しいセッション数だと思います

于 2012-09-13T05:23:37.743 に答える