我正在尝试加入公司及其详细信息,以及交易,即使它们不存在。
我正在计算交易数量,以确定有多少用户参加课程,如果没有交易,我仍然想加入公司和详细信息,但计数将为0,在我的查询中,正在选择training_company表,但是由于某种原因没有选择training_details:
SELECT training.*, count(distinct training_transactions.training_transaction_course) as completed_training_payments
FROM training
LEFT JOIN training_company
ON training.course_main = training_company_id
LEFT JOIN training_details
ON training.course_main = training_details_company
LEFT JOIN training_transactions
ON training.course_user = training_transactions.training_transaction_user
WHERE course_id = ?
AND training_transactions.training_transaction_status = 'complete'
AND training_transactions.training_transaction_payment_status = 'complete'
AND course_enabled = 'enabled'
training_company:
CREATE TABLE IF NOT EXISTS `training_company` (
`training_company_id` int(11) NOT NULL,
`training_company_name` varchar(100) NOT NULL,
`training_company_user` int(11) NOT NULL,
`training_company_enabled` varchar(50) NOT NULL DEFAULT 'enabled',
`training_company_has_avatar` int(5) NOT NULL DEFAULT '0',
`training_company_has_banner` int(5) NOT NULL DEFAULT '0'
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;
--
-- Dumping data for table `training_company`
--
INSERT INTO `training_company` (`training_company_id`, `training_company_name`, `training_company_user`, `training_company_enabled`, `training_company_has_avatar`, `training_company_has_banner`) VALUES
(1, '123', 1, 'enabled', 0, 0),
training_details:
CREATE TABLE IF NOT EXISTS `training_details` (
`training_details_id` int(11) NOT NULL,
`training_details_user` int(11) NOT NULL,
`training_details_company` int(11) NOT NULL,
`training_details_registration_number` varchar(10) NOT NULL,
`training_details_type` varchar(100) NOT NULL,
`training_details_name` varchar(100) NOT NULL,
`training_details_street` varchar(100) NOT NULL,
`training_details_town` varchar(100) NOT NULL,
`training_details_county` varchar(100) NOT NULL,
`training_details_postcode` varchar(100) NOT NULL,
`training_details_country` varchar(100) NOT NULL,
`training_details_company_name` varchar(100) NOT NULL,
`training_details_company_street` varchar(100) NOT NULL,
`training_details_company_town` varchar(100) NOT NULL,
`training_details_company_county` varchar(100) NOT NULL,
`training_details_company_postcode` varchar(100) NOT NULL,
`training_details_company_country` varchar(100) NOT NULL,
`training_details_total_employees` varchar(100) NOT NULL,
`training_details_fax` varchar(100) NOT NULL,
`training_details_landline` varchar(100) NOT NULL,
`training_details_mobile` varchar(50) NOT NULL,
`training_details_email` varchar(50) NOT NULL,
`training_details_website` varchar(250) NOT NULL,
`company_differs_address` int(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=latin1;
--
-- Dumping data for table `training_details`
--
INSERT INTO `training_details` (`training_details_id`, `training_details_user`, `training_details_company`, `training_details_registration_number`, `training_details_type`, `training_details_name`, `training_details_street`, `training_details_town`, `training_details_county`, `training_details_postcode`, `training_details_country`, `training_details_company_name`, `training_details_company_street`, `training_details_company_town`, `training_details_company_county`, `training_details_company_postcode`, `training_details_company_country`, `training_details_total_employees`, `training_details_fax`, `training_details_landline`, `training_details_mobile`, `training_details_email`, `training_details_website`, `company_differs_address`) VALUES
(1, 0, 1, '0', '', '123', '123', '123', '123456', 'WN8', 'Australia', '123', '123', '123', '', 'WN8', 'Australia', '', '', '', '', '', '', 4),
训练:
CREATE TABLE IF NOT EXISTS `training` (
`course_id` int(11) NOT NULL,
`course_user` int(11) NOT NULL,
`course_main` int(11) NOT NULL,
`course_type` varchar(255) NOT NULL,
`course_name` varchar(255) NOT NULL,
`course_description` text NOT NULL,
`course_location` varchar(255) NOT NULL,
`course_duration` varchar(255) NOT NULL,
`course_fitness_type` varchar(255) NOT NULL,
`course_instructor_name` varchar(255) NOT NULL,
`course_price` int(15) NOT NULL,
`course_start_date` date NOT NULL,
`course_max_attendees` int(8) NOT NULL,
`course_accommodation` varchar(255) NOT NULL,
`course_accommodation_price` varchar(255) NOT NULL,
`course_status` varchar(50) NOT NULL,
`course_enabled` varchar(10) NOT NULL DEFAULT 'enabled',
`course_location_name` varchar(255) NOT NULL,
`course_location_street` varchar(255) NOT NULL,
`course_location_town` varchar(255) NOT NULL,
`course_location_county` varchar(255) NOT NULL,
`course_location_postcode` varchar(255) NOT NULL,
`course_location_country` varchar(255) NOT NULL,
`course_certificate` varchar(250) NOT NULL,
`course_certificate_valid` int(30) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
--
-- Dumping data for table `training`
--
INSERT INTO `training` (`course_id`, `course_user`, `course_main`, `course_type`, `course_name`, `course_description`, `course_location`, `course_duration`, `course_fitness_type`, `course_instructor_name`, `course_price`, `course_start_date`, `course_max_attendees`, `course_accommodation`, `course_accommodation_price`, `course_status`, `course_enabled`, `course_location_name`, `course_location_street`, `course_location_town`, `course_location_county`, `course_location_postcode`, `course_location_country`, `course_certificate`, `course_certificate_valid`) VALUES
(1, 3, 1, 'Hazardous', '123', 'dddddddddddddd', 'other', '14', 'lol', 'lol', 123, '2015-11-09', 4, '0', '', 'pending', 'enabled', '123', '123', '123', '123456', '123', 'Australia', '123', 2),
那么我怎样才能让我的联盟处理细节问题,因为即使所有内容都匹配,目前它还没有加入
答案 0 :(得分:5)
正如Gordon Linoff在第一条评论中所建议的那样,将training_transactions
条款中涉及WHERE
的条件移至LEFT JOIN
。
当然,您还应该明确列出列而不是*
,并为GROUP BY
添加相应的COUNT
。
SELECT
training.course_id
,training.course_user
...
,count(distinct training_transactions.training_transaction_course) as completed_training_payments
FROM
training
LEFT JOIN training_company ON training.course_main = training_company_id
LEFT JOIN training_details ON training.course_main = training_details_company
LEFT JOIN training_transactions
ON training_transactions.training_transaction_user = training.course_user
AND training_transactions.training_transaction_status = 'complete'
AND training_transactions.training_transaction_payment_status = 'complete'
WHERE
training.course_id = ?
AND training.course_enabled = 'enabled'
GROUP BY
training.course_id
,training.course_user
...
在此查询中,您还应该注意一些事项。
WHERE
course_id = ?
AND course_enabled = 'enabled'
对于阅读该问题的新人(因为每个人都在阅读这个问题以及将要维护您的代码的下一个人,这可能是您在两年时间内)这些字段属于哪个表格,目前尚不清楚。始终尝试明确指出表格,如下所示:
WHERE
training.course_id = ?
AND training.course_enabled = 'enabled'
使用别名也很有帮助。
以类似的方式,不清楚JOIN
:
LEFT JOIN training_company ON training.course_main = training_company_id
LEFT JOIN training_details ON training.course_main = training_details_company
在简化此问题的查询时,这只是一个疏忽,或者这是您真正的代码吗?无论如何,请包括表名(或别名)。
LEFT JOIN training_company ON training.course_main = training_company.training_company_id
LEFT JOIN training_details ON training.course_main = training_details.training_details_company
答案 1 :(得分:1)
我建议完全不同的路线,不要使用左连接。由于您需要来自训练表的所有数据,并且您希望从不同的表中聚合(在您的情况下计数),我建议将聚合分解为单独的子查询。这就是我的意思(注意我在表格中添加了别名以简化操作):
SELECT t.*,
(SELECT count(distinct tt.training_transaction_course)
FROM training_company tc
JOIN training_details td ON td.course_main = tc.training_details_company
JOIN training_transactions tt ON t.course_user = tt.training_transaction_user
WHERE t.course_main = tc.training_company_id
AND tt.training_transaction_status = 'complete'
AND tt.training_transaction_payment_status = 'complete')
as completed_training_payments
FROM training t
WHERE t.course_id = ?
AND t.course_enabled = 'enabled'
这将保证训练表中与输入的course_id匹配的每一行返回一行。此外,如果子查询没有返回任何行,则它将返回0.
答案 2 :(得分:0)
这有一些问题。首先,如果没有training_transactions
的模式,很难重现。
此外,从您的描述和架构中可以看出,您希望在第一个表上进行内部联接。如果我读得对,training
总会有一家公司。 training_details
似乎与查询无关,如果它们不是,则会提供交叉产品,因此完全不考虑。
我假设用户加入交易是错误的,因为你有一个training_transaction_course我认为是正确的外键。
计数是错误的 - 它不是如何工作的,如果你想要计数,你需要一个GROUP BY子句。
WHERE子句对我来说是正确的,因为元素没有在任何连接中使用。
这会给你这样的东西:
SELECT training.course_id, -- everything you put here needs to go in the group by clause
count(training_transactions.training_transaction_course) as completed_training_payments
FROM training
JOIN training_company
ON training.course_main = training_company_id
LEFT JOIN training_transactions
ON training.course_id = training_transactions.training_transaction_course
WHERE course_id = ?
AND training_transactions.training_transaction_status = 'complete'
AND training_transactions.training_transaction_payment_status = 'complete'
AND course_enabled = 'enabled'
GROUP BY training.course_id, training_transactions.training_transaction_course
〜
答案 3 :(得分:0)
问题是您的查询从不会产生多行。
使用Groupby或嵌套查询,如其他答案中所述。