2015-06-18 5 views
0

Я пытаюсь запросить iSeries DB2 v6r1m0. Обычно я тестирую свои операторы SQL в System i Navigator перед их использованием в ADO.Net.Группа DB2 Только таблица 2 делает дубликаты

Я проследил свою проблему до этого, но я не уверен, как это исправить.

 
SELECT 
    a.id 
    , a.otherstuff 
    , MAX(a.date || ' ' || a.time) as adatetime /* I'm sure it's not this line */ 
    , b.id 
    , b.city 
    , b.state 
    , MAX(b.date || ' ' || b.time) AS bdatetime 
FROM 
    table1 a 

INNER JOIN 
    table2 b 
ON a.id = b.id 

GROUP BY 
    a.id, a.otherstuff, b.id, b.city, b.state 

Что происходит, что он показывает все b.cities и b.states, даже если я просто хочу b.city и b.state с максимальным значением.

 
a.id a.otherstuff a.adatetime  b.id b.city   b.state b.datetime 
a.dup1 a.dup1   a.dup1   b.dup1 San Francisco CA  1-Jan 1:00 
a.dup1 a.dup1   a.dup1   b.dup1 Sacramento  CA  1-Jan 2:00 
a.dup1 a.dup1   a.dup1   b.dup1 other cities WA  11-Jan 3:00 
a.dup2 a.dup2   a.dup2   b.dup2 San Francisco CA  11-Jan 1:00 
a.dup2 a.dup2   a.dup2   b.dup2 Sacramento  CA  11-Jan 2:00 
a.dup2 a.dup2   a.dup2   b.dup2 other cities WA  11-Jan 3:00 

Почему это происходит?

+0

_ "Я просто хочу b.city и b.state с max value "_ - как это отражается в условиях запроса? Подсказка: условия обычно появляются в предложении 'WHERE'. – mustaccio

+0

Просьба также показать результат, который вы хотите. – WarrenT

ответ

1

Это сложно с псевдокодом, как это, но я думаю, вам нужно присоединиться не непосредственно к таблице2, а производным запросом на основе таблицы2.

... 
FROM 
    table1 a 
    INNER JOIN 
    (
    SELECT 
     table2.* 
    FROM 
     (
     SELECT 
      table2.id, 
      MAX(table2.datetime) AS MaxDateTime 
     ) DerivedMax 
     LEFT OUTER JOIN 
     table2 ON table2.datetime = DerivedMax.MaxDateTime AND table2.id = DerivedMax.id 
    ) DerivedOnlyRowsFromTable2YouCareAbout ON a.id = DerivedOnlyRowsFromTable2YouCareAbout.id 

В зависимости от того, как данные существуют в вашей таблице1, может потребоваться такое же лечение. Если этого недостаточно, чтобы быть полезным, я бы попросил вас создать sqlfiddle с фактической структурой и данными для игры. Как я уже сказал, псевдокод может оставить желать лучшего.

+0

База данных - это DB2 for i v6.1, которая имеет несколько иной синтаксис, но близка. SQLfiddle не поддерживает эту платформу. – WarrenT

+0

DB2 - это не совсем моя рулевая рубка, но концепция в моем псевдокоде по-прежнему действительна (но может потребоваться синтаксические настройки?). Подзапрос получает только строки из таблицы2, которые вы, возможно, захотите присоединиться к соединению table1. Некоторые другие предлагаемые ответы здесь объединяют всю таблицу1 ко всей таблице2, а затем используют предложение WHERE, чтобы игнорировать результаты, которые включают нежелательные строки из таблицы2. Хотя функциональный эквивалент, концептуально, я думаю, что мой подход будет работать более эффективно, но, как я уже сказал, я не парень из DB2, поэтому я отдам будущему более осведомленному. – LDMJoe

+0

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

1

Используя GROUP BY, ваш результирующий набор будет содержать (одну) строку для каждой уникальной комбинации значений в перечисленных столбцах. Таким образом, если все выбранные и сгруппированные по столбцам в таблице1 не будут иметь одинаковые значения, вы получите более одной строки, даже не присоединившись ко второй таблице.

Если вы просто хотите b.city и b.state с максимальным значением, необходимо выделить соответствующую строку (ы) с помощью WHERE условия - как это было предложено @mustaccio.

Что-то вдоль

SELECT 
    a.id 
    , a.otherstuff 
    , a.date_time 
    , b.city 
    , b.state 
    , b.date_time 
FROM 
    table1 a 
INNER JOIN 
    table2 b 
ON 
    a.id = b.id 
WHERE 
    b.date_time = (SELECT MAX(date_time) FROM table2) 
; 

следует предусмотреть, что.

Если вы хотите, а максимальное значение дата_время из table1 в ваш результат - независимо от того, из которого записи она идет, попробуйте

SELECT 
    a.id 
    , a.otherstuff 
    , (SELECT MAX(date_time) FROM table1) a_max_date_time 
    , b.city 
    , b.state 
    , b.date_time b_date_time 
FROM 
    table1 a 
INNER JOIN 
    table2 b 
ON 
    a.id = b.id 
WHERE 
    b.date_time = (SELECT MAX(date_time) FROM table2) 
; 

в действии: SQL Fiddle. (Извините - нет DB2 в SQL Fiddle и только один столбец date_time каждый.)

Прокомментируйте, если и как требуется дополнительная деталь/настройка. (Примерные данные и ожидаемый результат будут особенно полезны ...)

0

Вы сказали: «Я просто хочу, чтобы b.city и b.state с максимальным значением».

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

Вы мощь просто добавить предложение ORDER BY и FETCH FIRST в конце

SELECT 
     a.id 
     , a.otherstuff 
     , MAX(a.xdate || ' ' || a.xtime) as adateinfo /* I'm sure it's not this  line */ 
     , b.id 
     , b.city 
     , b.state 
     , MAX(b.xdate || ' ' || b.xtime) as bdateinfo 
    FROM table1 a 
    JOIN table2 b 
    ON a.id = b.id 
    GROUP BY 
    a.id, a.otherstuff, b.id, b.city, b.state, b.bdateinfo 
    ORDER BY 
    bdateinfo desc 
    FETCH FIRST ROW ONLY 

Однако, а не присоединиться и группа все эти записи, это, вероятно, гораздо более эффективно сузить ее до сначала одна запись в таблице2, особенно если файлы большие.

SELECT a.id 
    , a.otherstuff 
    , MAX(a.xdate || ' ' || a.xtime) as adateinfo 
    , b.city 
    , b.state 
    , b.bdateinfo 
    FROM table1 a 
    JOIN (
     SELECT id 
       ,city 
       ,state 
       ,xdate 
       ,xtime 
       ,(xdate || ' ' || xtime) AS bdateinfo 
      FROM table2 i 
      ORDER BY xdate DESC, xtime DESC 
      FETCH FIRST ROW ONLY 
     ) AS b 
     ON a.id = b.id 
GROUP BY 
    a.id, a.otherstuff, b.city, b.state, b.bdateinfo 

Таким образом, вы должны получить что-то вроде

ID OTHERSTUFF  ADATEINFO CITY    STATE BDATEINFO 
27 whatever stuff 1/05 3:00 San Francisco CA  1/11 1:00 

Будем надеяться, что это то, что вы хотели.


Сноска: Я упал b.id из результатов, казалось излишним и посторонними, так как она должна быть равна A.id

+0

Я еще не посмотрел на другие решения. Я бы подумал, что сначала попробую ваше решение, потому что еще один запрос, чтобы вытащить еще одну таблицу, было бы неплохо вытащить одну строку, но в моем случае главная таблица A имеет много строк. – Emwat

Смежные вопросы