这是我的sql (在mysql表中)
select * from(SELECT sample_register.usin,
DATE_FORMAT(sample_register.doc,'%d-%m-%Y') as doc1,
sample_register.location,
sample_register.description,
sample_register.type,
sample_allocation.gamma,
gamma_results.act,
gamma_results.act_sd,
gamma_results.mdl,
gamma_results.bdl,
DATE_FORMAT(count_dt,'%d-%m-%Y') as count_dt
FROM sample_register
LEFT JOIN sample_allocation
ON sample_register.usin=sample_allocation.usin
LEFT JOIN gamma_results
ON gamma_results.usin = sample_register.usin
AND gamma_results.istp='Cs137'
WHERE mid(sample_register.usin,3,1)='F'
AND sample_register.doc BETWEEN '2015-01-01'
AND '2015-03-31'
AND sample_register.category='ter'
AND sample_allocation.gamma='Y'
ORDER BY mid(sample_register.usin,3,1),
sample_register.doc,
sample_register.usin) AS a
LEFT JOIN (SELECT sample_register.usin,
gamma_results.act,
gamma_results.act_sd,
gamma_results.mdl,
gamma_results.bdl
FROM sample_register
LEFT JOIN gamma_results
ON gamma_results.usin = sample_register.usin
AND gamma_results.istp='k40'
WHERE mid(sample_register.usin,3,1)='F'
AND sample_register.doc
BETWEEN '2015-01-01'
AND '2015-03-31'
AND (sample_register.category='ter')
ORDER BY mid(sample_register.usin,3,1),
sample_register.doc,
sample_register.usin) AS b
ON a.usin=b.usingamma_results表中有4条记录。2015年10月4日和2015年4月18日各有两项记录。
USIN istp act count_dt
-----------------------------------------
15FML002 Cs137 0.00769 10/04/15
15FML002 K40 0 10/04/15
15FML002 Cs137 0.00608 18/04/15
15FML002 K40 12.117 18/04/15以下形式查询输出数据(为方便起见,我删除了一些字段)
15FML002 0.00769 Y 10/04/15 00
15FML002 0.00769 Y 10/04/15 12.117
15FML002 0.00608 Y 18/04/15 00
15FML002 0.00608 Y 18/04/15 12.117但是我想在两个记录中获得输出。就是这样的
15FML002 0.00769 Y 10/04/15 00
15FML002 0.00608 Y 18/04/15 12.117如何重新框住(连接或联合)查询以获得如下输出?/编辑于2015年4月30日
我无法创建一个sqlfiddle,因为在他们的网站上的一些问题。下面是两个表sample_register和gamma results的DDL和DML。此时可以忽略sample_allocation表。
CREATE TABLE `sample_register` (
`usin` varchar(11) NOT NULL,
`sample_id` varchar(7) NOT NULL,
`doc` date NOT NULL,
`location` varchar(255) DEFAULT NULL,
`category` varchar(50) DEFAULT NULL,
`type` varchar(255) DEFAULT NULL,
`description` varchar(255) DEFAULT NULL,
`fwt` decimal(10,2) DEFAULT NULL COMMENT 'This filed contains either fwt in gms or volume in ltr for milk or volume of air for particulate',
`dwt` decimal(10,2) DEFAULT NULL,
`ashwt` decimal(10,2) DEFAULT NULL,
`user` varchar(255) DEFAULT NULL,
`to_dt` date DEFAULT NULL COMMENT 'This is for particulate sample filter removal date',
`wc` decimal(10,2) DEFAULT NULL,
`oc` decimal(10,2) DEFAULT NULL,
`ac` decimal(10,2) DEFAULT NULL,
`status` varchar(1) DEFAULT NULL,
`remarks` varchar(255) DEFAULT NULL,
PRIMARY KEY (`usin`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO `sample_register` VALUES ('15FML002', 'NIL', '2015-04-09', 'MALLAPUR', 'ter', 'MILK', 'milk', '2000.00', null, null, '1604015', null, null, null, null, null, null);
DROP TABLE IF EXISTS `gamma_results`;
CREATE TABLE `gamma_results` (
`usin` varchar(255) NOT NULL,
`sysid` varchar(255) NOT NULL,
`count_time` decimal(10,0) DEFAULT NULL,
`geo` varchar(255) DEFAULT NULL,
`vol` decimal(10,2) DEFAULT NULL,
`energy` decimal(10,2) DEFAULT NULL,
`istp` varchar(255) DEFAULT NULL,
`bkg` decimal(10,5) DEFAULT NULL,
`eff` decimal(10,3) DEFAULT NULL,
`sigma` decimal(10,5) DEFAULT NULL,
`ncps` decimal(10,5) DEFAULT NULL,
`sd` decimal(10,5) DEFAULT NULL,
`mdl` decimal(10,5) DEFAULT NULL,
`act` decimal(10,5) DEFAULT NULL,
`act_sd` decimal(10,5) DEFAULT NULL,
`bdl` varchar(1) DEFAULT NULL,
`entry_time` datetime DEFAULT NULL,
`entered_by` int(11) DEFAULT NULL,
`count_dt` date DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
INSERT INTO `gamma_results` VALUES ('15FML002', 'HPGE2', '25000', 'nb', '1000.00', '364.48', 'I131', '0.01000', '3.400', '0.00190', '-0.01000', '0.00041', '0.06882', null, '0.00000', 'Y', '2015-04-13 10:24:11', '1619381', '2015-04-10');
INSERT INTO `gamma_results` VALUES ('15FML002', 'HPGE2', '25000', 'nb', '1000.00', '661.66', 'Cs137', '0.00020', '2.060', '0.00027', '-0.00020', '0.00006', '0.00769', null, '0.00000', 'Y', '2015-04-13 10:24:57', '1619381', '2015-04-10');
INSERT INTO `gamma_results` VALUES ('15FML002', 'HPGE2', '25000', 'nb', '1000.00', '1460.73', 'K40', '0.00500', '0.911', '0.00134', '-0.00450', '0.00032', '1.37855', null, '0.00000', 'Y', '2015-04-13 10:25:37', '1619381', '2015-04-10');
INSERT INTO `gamma_results` VALUES ('15FML002', 'HPGE2', '15000', 'nb50', '2000.00', '661.66', 'Cs137', '0.00020', '3.380', '0.00035', '-0.00020', '0.00006', '0.00608', null, '0.00000', 'Y', '2015-04-20 10:21:48', '1619381', '2015-04-18');
INSERT INTO `gamma_results` VALUES ('15FML002', 'HPGE2', '15000', 'nb50', '2000.00', '1460.73', 'K40', '0.00500', '1.550', '0.00173', '0.04008', '0.00176', '0.52302', '12.11700', '0.53200', 'N', '2015-04-20 10:23:00', '1619381', '2015-04-18');发布于 2015-04-30 21:56:46
我以前见过这样的输出。
这是由连接中的一个小错误引起的。如果我没记错的话,我通过嵌套我的一些连接作为子查询解决了这个问题,所以我沿着连接将每个表添加到现有的表中。我可能过多地混合了,但它确实工作得很好。(更新:是的,我现在明白了,这正是您正在做的事情)。
在某些情况下,连接并不是唯一的,或者您安排连接的方式也不是唯一的,因此SQL为您提供了它所能提供的所有组合。
(当然,假设让事情变得糟糕的不只是一个丢失的GROUP BY。这是类似问题的另一个来源。)
我会仔细检查一下你的SQL,看看我是否能发现问题所在,但稍微试错一下会快得多。
更新1:这要么是一个令人印象深刻的黑客攻击,要么是一个错误,我无法理解是哪一个。
LEFT JOIN gamma_results
ON gamma_results.usin = sample_register.usin
AND gamma_results.istp='Cs137' 我从来没有见过条件作为连接的一部分。我不能告诉您这是否有效,但我的直觉反应是希望将其放在WHERE子句中。请随时带我去学校,因为你似乎知道你在做什么,而我并没有实际的项目(我也不是什么都知道)。
更新2:鉴于您的硬编码连接必须接近正常工作,我的感觉是我希望在嵌套的SELECT中使用GROUP by,因为您正在使用聚合函数(count)。
我记得有一次做了一个相当复杂的查询,当你深入到它的时候,实际上是说"for each table_a add table_b“。诚实地与GROUP BY交朋友,如果这不能解决你的问题,那么我就是一只无伤大雅的小猴子。
发布于 2015-04-25 22:13:48
首先,如果您需要查询某个特定数据集的帮助,您应该提供相同的数据和sqlfiddle。
由于我没有小提琴的数据,下面是我的猜测:
SELECT sample_register.usin,
DATE_FORMAT(sample_register.doc,'%d-%m-%Y') as doc1,
sample_register.location,
sample_register.description,
sample_register.type,
sample_allocation.gamma,
gr.act,
gr.act_sd,
gr.mdl,
gr.bdl,
gr.count_dt,
grK40.act
FROM sample_register
INNER JOIN sample_allocation
ON sample_register.usin=sample_allocation.usin
AND sample_allocation.gamma='Y'
LEFT JOIN (
SELECT
usin,
act,
act_sd,
mdl,
bdl,
count_dt,
DATE_FORMAT(count_dt,'%d-%m-%Y') as count_dt_formatted
FROM gamma_results
WHERE istp='Cs137'
) gr
ON gr.usin = sample_register.usin
LEFT JOIN gamma_results grK40
ON grK40.usin = gr.usin
AND grK40.istp='k40'
AND grK40.count_dt = gr.count_dt
WHERE mid(sample_register.usin,3,1)='F'
AND sample_register.doc BETWEEN '2015-01-01' AND '2015-03-31'
AND sample_register.category='ter'
ORDER BY mid(sample_register.usin,3,1),
sample_register.doc,
sample_register.usin但这只是一种猜测,因为它在我看来非常奇怪。
你写道:
gamma_results表中有4条记录。分别为10/04/2015和18/04/2015的两个记录。:istp,act,,USIN count_dt,但在您的查询中使用act,act_sd,mdl,bdl,DATE_FORMAT(count_dt,'%d-%m-%Y') as count_dt,因此我们可以假设您在那里有一些其他列,如:act_sd,mdl,bdl。
下面写道:查询输出数据,格式如下(为了方便起见,我删除了一些字段)
15FML002 0.00769 Y 10/04/15 00
15FML002 0.00769 Y 10/04/15 12.117即使删除了一些字段,这里又有哪些字段?
逻辑上是:usin,act,未知,count_dt,未知(当istp='K40'时等于act )。但这是不可能的,因为您的查询请求中没有这样的字段。在我看来,所提供输出是作为其他查询的结果而获得的,而不是您向我们显示的查询。
但到目前为止,我的猜测是这样的。如有任何问题,欢迎光临。
发布于 2015-05-02 13:10:53
您编写的每个表都应该有一个PRIMARY KEY。这在关系数据库中是一个非常重要的概念。虽然您在sample_register中有PRIMARY KEY,但在gamma_results中没有。
如果你有一个主键,这就是在公园里散步(相对而言)
假设您有以下行:
15FML002 0.00769 Y 10/04/15 00
15FML002 0.00769 Y 10/04/15 12.117
15FML002 0.00608 Y 18/04/15 00
15FML002 0.00608 Y 18/04/15 12.117假设这些实际上是数据库中不同行的副本,分配主键将创建一个新列,该列将使您的数据如下所示:
1 15FML002 0.00769 Y 10/04/15 00
1 15FML002 0.00769 Y 10/04/15 12.117
2 15FML002 0.00608 Y 18/04/15 00
2 15FML002 0.00608 Y 18/04/15 12.117对于您的示例来说,这有点过于简单化了,考虑到在问题内部的解释中,您声明了
对于每个USIN,单个count_dt上的istp有两个不同的值。因此,在每个计数日期,一个USIN将有两个记录,其中一个为istp='k40‘,另一个为istp=cs137。因为USIN和count date很常见,所以我想在一行中显示它。然后,如果一个USIN有多个(比如‘n')计数日期,那么就会有nx2记录。但我只需要n行。
我知道您理解这些数据是如何组合在一起的,但是如果您能够告诉SQL数据库这些数据是如何以它所理解的语言组合在一起的,那么您的SQL查询就会变得更加清晰和整洁。
了解主键的去向将帮助您更好地从逻辑上理解表结构。如果您不能分配主键,这意味着表可能需要拆分成块。这一个当然可以从一些标准化中受益。
显然,您在USIN上具有1:n关系,这在这里得到了很好的表示,但您在istp上也具有1:2关系。这不会反映在不同的表中,而是全部反映在同一个表中,这意味着当USIN和count_dt的组合完全相同时,它们会在整个表中重复两次。
我并不是说你不能让这个查询工作。您所需要做的就是在底部粘贴一个GROUP BY。但是,在没有索引的情况下,表的执行速度将非常慢。即使有了索引,它也会比需要的速度慢!重要的是,如果没有PRIMARY KEY,你的SQL数据库将会做比它需要的更多的工作。
理想的方式
如果您将表一分为二,为每个USIN/count_dt对提供一个新的PRIMARY KEY,然后创建另一个满足您的istp='k40'和istp=cs137需求的表,那么您将只需要在已经很长的查询中额外编写一行查询,这通常会为您节省大量查询时间。
代替SELECT * FROM tableA LEFT JOIN tableB on tableA.USIN=tableB.USIN...,你可以这样写:
SELECT * FROM tableA
LEFT JOIN tableB on tableA.USIN=tableB.USIN
LEFT JOIN tableX on tableB.id = tableX.tableB_id
....您应该最终得到相同的数据集。如果你只想要唯一的值,你需要做的就是去掉第二个JOIN。
如果您不能更改表结构
如果由于某种原因不能更改表结构,那么您可以选择创建一个由USIN、count_dt和istp组成的复合主键,因为它们应该是唯一的,并且应该只在表中以特定的组合出现一次。这可以很快地扩展,但应该会给你大体的要点。
要使用此方法创建不同的值,您应该在USIN和count_dt上有一个复合索引,然后使用GROUP BY USIN, count_dt。
https://stackoverflow.com/questions/29838659
复制相似问题