【问题标题】:Get Multiple COUNTS Multiple JOINS from Schedule table从 Schedule 表中获取 Multiple COUNTS Multiple JOINS
【发布时间】:2014-03-10 05:38:13
【问题描述】:

我有 3 张桌子:

test_membertest_member_addon & test_schedule

  • 一个成员只能有 1 个 test_member.Type (test_schedule.prod_type = 1)
  • 一个成员可以有多个test_member_addon.Type (test_schedule.prod_type = 2)

我正在尝试为未来日期和schedule.status = 1 的计划中的每个 DISTINCT test_schedule.mem_ID、test_schedule.Prod_Code 返回不同计数。

时间表应该有正确的付款金额,例如。 52 为“每周”。如果Correct & Actual 不匹配,我可以修复。

我的查询:不返回正确的 AmountPeriodCorrectActual 值。

SELECT DISTINCT s.mem_ID,
CASE WHEN s.prod_type = 1 THEN ROUND(m.next_amount,2) ELSE ROUND(ma.next_amount,2) END AS Amount, 
CASE WHEN s.prod_type = 1 THEN m.Period ELSE ma.Period END AS Period,
CASE WHEN s.prod_type = 1 THEN 
(
CASE WHEN m.Period = 'Weekly' THEN 52 
WHEN m.Period = 'Fortnightly' THEN 27 END
)
ELSE
(
CASE WHEN ma.Period = 'Weekly' THEN 52 
WHEN ma.Period = 'Fortnightly' THEN 27 END 
)
END AS Correct,
COUNT(*) AS Actual, 
s.prod_code, 
s.prod_type
FROM `test_schedule` s, `test_member` m, `test_member_addon` ma 
WHERE m.ID = s.mem_ID AND ma.mem_ID = m.ID 
AND s.status = 1 
GROUP BY s.prod_code, s.mem_ID 
ORDER BY s.mem_ID, s.prod_type;

数据库构建脚本:

CREATE TABLE `test_member` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `next_amount` float DEFAULT NULL,
  `period` varchar(50) DEFAULT NULL,
  `prod_code` int(11) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;

INSERT INTO `test_member` (`ID`, `next_amount`, `period`, `prod_code`) VALUES
('1','50','Weekly',11),
('2','35','Fortnightly',11);

CREATE TABLE `test_member_addon` (
  `mem_addon_ID` int(11) NOT NULL AUTO_INCREMENT,
  `mem_ID` int(11) DEFAULT NULL,
  `next_amount` float DEFAULT NULL,
  `period` varchar(50) DEFAULT NULL,
  `prod_code` int(11) NOT NULL,
  PRIMARY KEY (`mem_addon_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;

INSERT INTO `test_member_addon` (`mem_addon_ID`, `mem_ID`, `next_amount`, `period`, `prod_code`) VALUES
('1','1','25.55','Weekly',22),
('2','1','15','Fortnightly',33);

CREATE TABLE `test_schedule` (
  `sched_ID` int(11) NOT NULL AUTO_INCREMENT,
  `mem_ID` int(11) NOT NULL,
  `prod_code` int(11) NOT NULL,
  `prod_type` int(11) NOT NULL,
  `status` smallint(4) NOT NULL,
  `amount` float NOT NULL,
  `sched_date` date NOT NULL,
  PRIMARY KEY (`sched_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=latin1;

INSERT INTO `test_schedule` (`sched_ID`, `mem_ID`, `prod_code`, `prod_type`, `status`, `amount`, `sched_date`) VALUES
('1','1','11','1','1','50','2014-03-21'),
('2','1','11','1','1','50','2014-03-28'),
('3','1','11','1','1','50','2014-04-04'),
('4','1','11','1','1','50','2014-04-11'),
('5','1','11','1','1','50','2014-04-18'),
('6','1','22','2','1','25.55','2014-03-21'),
('7','1','22','2','1','25.55','2014-03-28'),
('8','1','22','2','1','25.55','2014-04-04'),
('9','1','22','2','1','25.55','2014-04-11'),
('10','1','22','2','1','25.55','2014-04-18'),
('11','1','22','2','1','25.55','2014-04-25'),
('12','1','22','2','1','25.55','2014-05-02'),
('13','1','22','2','1','25.55','2014-05-09'),
('14','1','33','2','1','15','2014-03-21'),
('15','1','33','2','1','15','2014-04-04'),
('16','1','33','2','1','15','2014-04-18'),
('17','1','33','2','1','15','2014-05-02'),
('18','1','33','2','1','15','2014-05-16'),
('19','1','33','2','1','15','2014-05-30'),
('20','1','33','2','1','15','2014-06-13'),
('21','1','33','2','1','15','2014-06-27');

Current Return Data:
mem_ID |    Amount   |    Period    | Correct  |  Actual  |prod_code | prod_type
1      |    50.00    |    Weekly    |    52    |    10    |    11    |    1
1      |    25.55    |    Weekly    |    52    |    16    |    22    |    2
1      |    25.55    |    Weekly    |    52    |    16    |    33    |    2 

Correct Data:
mem_ID |    Amount   |    Period    | Correct  |  Actual  |prod_code | prod_type
1      |    50.00    |    Weekly    |    52    |    5     |    11    |    1
1      |    25.55    |    Weekly    |    52    |    8     |    22    |    2
1      |    15       | Fortnightly  |    27    |    8     |    33    |    2 

【问题讨论】:

  • test_schedule.mem_id 的不同计数...您要计算什么?表中每个成员的不同行数? test_schedule.Prod_Code...你只想要每个成员的不同 prod_codes 吗?
  • 嗨,约翰。我正在尝试返回:每个 mem_ID、prod_code 的行数(实际应该返回 5 代表 prod_code 11、8 代表 22 和 8 代表 33)+ 期间 + 期间计数(正确的两周一次为 27,每周 52)+即。在我给出的例子中
  • 抱歉添加错了。在示例中,我给出了返回数据将所有“实际”计数加倍,并返回金额、期间(所有每周)和正确(所有 52)的不正确值。
  • 我已经添加了当前返回数据和预期返回数据。
  • 如何从当前的表模式中判断test_schedule 中使用了哪个时期?现在你不提供这个。唯一的解决方法是使用数量来适当地加入,但这绝对是错误的。也不要将浮点数用于货币价值。而是使用精确的数据类型:小数(例如小数(10, 2)或小数(10, 3))或整数(并以美分存储货币值)。

标签: mysql join group-by


【解决方案1】:

试试这个方法

SELECT mem_id, prod_code, prod_type, period, 
       ROUND(MAX(amount), 2) amount, 
       CASE WHEN period = 'Weekly' THEN  52 ELSE 27 END correct,      
       COUNT(*) actual
  FROM
(
  SELECT s.*, m.period
    FROM test_schedule s JOIN test_member m
      ON s.mem_id = m.id 
     AND s.prod_code = m.prod_code
     AND s.prod_type = 1
   WHERE s.status = 1 
  UNION ALL 
  SELECT s.*, a.period
    FROM test_schedule s JOIN test_member_addon a 
      ON s.mem_id = a.mem_id 
     AND s.prod_code = a.prod_code
     AND s.prod_type = 2
   WHERE s.status = 1 
) q
 GROUP BY mem_id, prod_code, prod_type, period

输出:

| MEM_ID |产品代码 |产品类型 |期间 |数量 |正确 |实际 | |--------|-----------|------------|-------------|-- ------|---------|--------| | 1 | 11 | 1 |周刊 | 50 | 52 | 5 | | 1 | 22 | 2 |周刊 | 25.55 | 52 | 8 | | 1 | 33 | 2 |双周刊 | 15 | 27 | 8 |

这里是SQLFiddle演示

【讨论】:

  • 非常感谢彼得姆。几个月来我一直在寻找这个答案。明天我会坐下来学习,所以我可以理解这个过程。非常感谢。如果我奖励你积分,我该怎么做?
  • 不客气 :) 你可以upvote and accept如果它是你要找的答案。
猜你喜欢
  • 2012-08-03
  • 2015-08-16
  • 1970-01-01
  • 1970-01-01
  • 2015-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-15
相关资源
最近更新 更多