用于在列中显示行数据的SQL

时间:2015-04-24 04:22:52

标签: php mysql

这是我的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.usin

gamma_results表中有4条记录。 2015年4月10日和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结果的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');

4 个答案:

答案 0 :(得分:8)

之前我见过这样的输出。

这是由于连接中的微小错误引起的。如果我没记错的话,我通过将一些连接嵌套为子查询来解决这个问题,所以我将每个表添加到一个连接的现有表中。我可能过度混合但它确实很好用。 (更新:是的,我现在看到的正是你正在做的事情)。

在该混合中的某个时刻,连接并不是唯一的,或者您安排它的方式并不是唯一的,因此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 )。

我记得曾经做过一个非常复杂的查询,当你明白它时,它实际上是在为每个table_a添加table_b"。诚实地与GROUP BY交朋友,如果这不能解决你的问题,那么我就是一只小的无害的猴子。

答案 1 :(得分:4)

首先,如果您需要有关某些特定数据集查询的帮助,则应提供相同的数据和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条记录。 2015年4月10日和2015年4月18日各有两条记录:USINistpactcount_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未知act时等于istp='K40' )。但这是不可能的,因为你的查询请求中没有这样的字段。在我看来,提供的输出是由于其他一些查询得到的,而不是你向我们展示的那个。

但到目前为止,这是我的猜测。如果有任何问题,欢迎您。

答案 2 :(得分:3)

您撰写的每个表都应该有一个PRIMARY KEY。这是关系数据库中一个至关重要的概念。如果PRIMARY KEY中有sample_register,则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

对于您的示例,这有点过于简单化,考虑到在您的问题内部的解释中,您说明了

  

对于每个USIN,单个count_dt上的istp有两个不同的值。因此,在每个计数日期,USIN将有两个记录,其中一个用于istp =' k40'另一个是istp = cs137。由于USIN和计数日期很常见,我想将它显示在一行中。然后,如果USIN有多个(比如' n')计数日期,则会有nx2个记录。但我只需要n行。

我知道你了解这些数据是如何组合在一起的,但是如果你能够告诉SQL数据库数据如何以它理解的语言融合在一起,那么你的SQL查询将变得更清洁和更整洁。

了解主键的位置将有助于您更好地逻辑理解表结构。如果您无法分配主键,则表示该表可能需要拆分为块。这个当然可以从一点规范化中受益。

显然,istp上有一个1:n的关系,这里有很好的代表,但你在USIN上的关系也是1:2。这不会反映在不同的表中,而是反映在同一个表中,这意味着count_dtGROUP BY的组合在整个表中重复两次时完全相同。

我并不是说您无法使此查询有效。您需要做的就是在底部粘贴PRIMARY KEY。但是,没有索引可以说你的桌子会非常慢。即使使用索引,它也会比它需要的速度慢!重要的是,没有PRIMARY KEY你的SQL数据库将会做很多工作而不是远远需要。

理想的方式

如果您将表格拆分为两个,为每个USIN / count_dt对提供新的istp='k40',那么请创建另一个表格来解决您的istp=cs137和{{1在您已经很长的查询中,您只需要编写一行额外的查询,而且可能更多的时间可以节省您大量的查询时间。

而不是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

如果您无法更改表格结构

如果由于某种原因您无法更改表格结构,那么您可以选择创建一个由USINcount_dtistp组成的复合主键,因为这些应该是唯一的,应该只在表格中显示一次特定的组合。这可以迅速膨胀,但应该给你一般的要点。

要使用此方法创建不同的值,您应该在USINcount_dt上有一个复合索引,然后使用GROUP BY USIN, count_dt

答案 3 :(得分:0)

@masoondreamz,我为可能的解决方案创造了一个小提琴。它是 - http://sqlfiddle.com/#!9/5bcae/27/0

解决方案的基本要素是我按Count_DT列中的日期进行分组,并将其添加到子查询的关节条件中。我确实将列数修改为您在示例结果中显示的列表。