Подтвердить что ты не робот

SQL для отображения данных строк в столбцах

Вот мой 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 записи. по две записи за 10/04/2015 и 18/04/2015.

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

Как я могу перерисовать (объединить или объединить) запрос для получения вывода следующим образом? /// отредактировано 30/04/2015

Я не могу создать sqlfiddle из-за некоторого proplem на их сайте. Вот DDL и DML для двух таблиц sample_register и gamma results. Таблицу 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');
4b9b3361

Ответ 1

Я видел такой вывод раньше.

Это вызвано крошечной ошибкой в ​​соединении. Если я правильно помню, я решил это, вложив некоторые из моих соединений в качестве подзапросов, поэтому я добавлял каждую таблицу в существующую таблицу по соединению. Я, вероятно, перебрал микс, но он отлично работал. (ОБНОВЛЕНИЕ: Да, теперь я вижу, что это именно то, что вы делаете).

В какой-то момент в этом соединении соединение не было уникальным или способ, которым вы его организовали, не был уникальным, и поэтому SQL предоставил вам все комбинации, которые он мог бы придумать.

(Предполагая, конечно, что это не просто недостающее GROUP BY, что расстраивает вещи. Это другой источник таких проблем.)

Я внимательно изучу ваш SQL и посмотрю, смогу ли я обнаружить проблему, но немного проб и ошибок будет намного быстрее.

ОБНОВЛЕНИЕ 1: Это действительно впечатляющий взлом или ошибка, и я не могу понять, что.

LEFT JOIN gamma_results    
ON gamma_results.usin = sample_register.usin    
AND gamma_results.istp='Cs137' 

Я никогда не видел условное соединение как часть соединения. Я не мог сказать вам, будет ли это работать, но моя реакция на кишок состоит в том, чтобы поместить это в предложение WHERE. Не стесняйтесь взять меня в школу на этом, поскольку вы, кажется, знаете, что делаете, и у меня нет рук в реальный проект (и я не знаю все).

Обновление 2: Учитывая, что ваше жесткое кодированное соединение должно быть близко к работе, я чувствую, что хочу, чтобы GROUP выполнялась во вложенном SELECT, когда вы используете агрегированные функции (count).

Я помню, как однажды сделал довольно сложный запрос, который, когда вы добрались до него, действительно говорил "для каждого table_a add table_b". Честно подружитесь с GROUP BY, и если это не решит вашу проблему, тогда я маленькая безобидная обезьяна.

Ответ 2

Прежде всего, вы должны предоставить одинаковые данные и 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.: USIN, istp, act, 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, UNKNOWN, count_dt, UNKNOWN (равно act, когда istp='K40'). но это невозможно, потому что у вас нет такого поля в запросе запроса. Мне кажется, что результат был получен в результате какого-то другого запроса, а не того, который вы нам показываете.

Но пока это моя догадка. Приглашаем вас на любые вопросы.

Ответ 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

Это немного упрощает ваш пример, учитывая, что внутри объяснения внутри вашего вопроса вы заявили, что

Для каждого USINs существует два разных значения для istp на одном count_dt. Следовательно, на каждую дату счета будут две записи для USIN с одной для istp = 'k40', а другая для istp = cs137. Поскольку USIN и дата подсчета являются общими, я хочу отобразить их в одной строке. Затем, если в USIN указано несколько дат подсчета (например, n), тогда будут записи nx2. Но мне нужно только n строк.

Я понимаю, что вы понимаете, как эти данные подходят друг к другу, но ваши SQL-запросы станут более чистыми и более аккуратными, если вы сможете сообщить базе данных SQL, как данные соответствуют друг другу на языке, который он понимает.

Чтобы понять, куда идет ваш основной ключ, вы сможете лучше логически понять структуру вашей таблицы. Если вы не можете назначить первичный ключ, это означает, что таблица, вероятно, нужно разбить на куски. Это, безусловно, может выиграть от небольшой нормализации.

Очевидно, что у вас есть отношение 1: n на USIN, которое здесь хорошо представлено, но у вас также есть соотношение 1: 2 на istp. Это не отражается в другой таблице, но вместо этого все в одной таблице, что означает, что комбинации USIN и count_dt повторяются дважды по всей таблице, когда они являются точно такими же.

Я не предлагаю, чтобы вы не могли заставить этот запрос работать. Все, что вам нужно сделать, это придерживаться GROUP BY внизу. Однако, без каких-либо указателей говорить о вашей таблице будет невероятно медленно. Даже с индексами он будет медленнее, чем нужно! Важно отметить, что без PRIMARY KEY ваша база данных SQL будет делать больше работы, чем нужно, с помощью длинного снимка.

Идеальный способ

Если вы разделите свои таблицы на две части, предоставив новую PRIMARY KEY для каждой пары USIN/count_dt, затем создайте другую таблицу, которая устанавливает ваши требования 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.

Ответ 4

@masoondreamz, я создал скрипку для возможного решения. Это - http://sqlfiddle.com/#!9/5bcae/27/0

Существенным элементом решения я был сгруппирован по дате в столбце Count_DT и добавил его в совместное условие для подзапросов. Я обрезал количество столбцов в списке, который вы показали в примере.