2016-05-20 3 views
0

Я написал запрос для сравнения 2 столбцов в разных таблицах (TRELAY VS TUSERDEF8). Запрос работает отлично, за исключением того, что он извлекает верхнюю запись в таблице TUSERDEF8, которая имеет отношение много к одному к таблице TRELAY.SQL-запрос для извлечения последней записи из связанной таблицы

Столы связаны TRELAY.ID = TUSERDEF8.N01. Я хотел бы получить последнюю запись от TUSERDEF8 и сравнить эту запись с записью TRELAY. Я планирую использовать максимальное значение столбца индекса (TUSERDEF8.ID) для определения последней записи.

Я использую SQL Server.

Мой код ниже, но я не уверен, как изменить запрос, чтобы получить последнюю запись TUSERDEF8. Любая помощь приветствуется.

SELECT 
    TRELAY.ID, TRELAY.S15, 
    TUSERDEF8.S04, TUSERDEF8.N01, TUSERDEF8.S06 
FROM 
    TRELAY 
INNER JOIN 
    TUSERDEF8 ON TRELAY.ID = TUSERDEF8.N01 
WHERE 
    LEFT(TRELAY.S15, 1) <> LEFT(TUSERDEF8.S04, 1) 
    AND NOT (TRELAY.S15 LIKE '%MEDIUM%' AND 
      TUSERDEF8.S04 LIKE '%N/A%' AND 
      TUSERDEF8.S06 LIKE '%EACMS%') 

ответ

-1

Использование столбца ID, чтобы определить, какая строка является «последним» плохая идея

Используя загадочные имена таблиц, как «TUSERDEF8» (как он отличается от TUSERDEF7) - очень плохая идея, а также полные загадочные имена столбцов, такие как «S04».

Использование префиксов типа «Т» для таблицы - плохая идея - уже должно быть ясно, что это таблица.

Теперь, когда все это из пути:

SELECT 
    R.ID, 
    R.S15, 
    U.S04, 
    U.N01, 
    U.S06 
FROM 
    TRELAY R 
INNER JOIN TUSERDEF8 U ON U.N01 = R.ID 
LEFT OUTER JOIN TUSERDEF8 U2 ON 
    U2.N01 = R.ID AND 
    U2.ID > U.ID 
WHERE 
    U2.ID IS NULL AND -- This will only happen if the LEFT OUTER JOIN above found no match, meaning that the row in U has the highest ID value of all matches 
    LEFT(R.S15, 1) <> LEFT(U.S04, 1) AND 
    NOT (
     R.S15 LIKE '%MEDIUM%' AND 
     U.S04 LIKE '%N/A%' AND 
     U.S06 LIKE '%EACMS%' 
    ) 
+0

Некринированный дубликат логики в этом ответе: http://stackoverflow.com/a/2111420/1507566 –

+0

Это «некредитованный», потому что я только сам придумал запрос. Я не просматриваю интернет каждый раз, когда я набираю запрос, чтобы увидеть, мог ли кто-то еще его ввести его раньше. Вы даете кредит каждый раз, когда вы выписываете цикл «WHILE», потому что кто-то когда-то использовал его перед вами? –

+0

Только комментирование, чтобы объяснить причину моего нисходящего потока, а не быть личной критикой, и я, конечно же, не имел в виду, что вы намеренно плагиализировали. Я стараюсь не спускать без комментариев. Спасибо, что голосовали за закрытие. –

0

Я считаю, что ваш ожидаемый результат все еще немного неоднозначен.

Звучит так, как будто вы хотите только запись с выхода, на которой TUSERDEF8.ID находится на своем максимуме. Если это верно, то попробуйте следующее:

SELECT TRELAY.ID, TRELAY.S15, TUSERDEF8.S04, TUSERDEF8.N01, TUSERDEF8.S06 
FROM TRELAY 
    INNER JOIN TUSERDEF8 ON TRELAY.ID = TUSERDEF8.N01 
WHERE LEFT(TRELAY.S15, 1) <> LEFT(TUSERDEF8.S04, 1) 
    AND NOT (TRELAY.S15 LIKE '%MEDIUM%' AND 
      TUSERDEF8.S04 LIKE '%N/A%' AND 
      TUSERDEF8.S06 LIKE '%EACMS%') 
    AND TUSERDEF8.ID IN (SELECT MAX(TUSERDEF8.ID) FROM TUSERDEF8) 

EDIT: После просмотра последних комментариев, казалось бы, что-то вроде этого было бы более подходящим:

SELECT 
    , C.ID 
    , C.S15, 
    , D.S04 
    , D.N01 
    , D.S06 
FROM (
    SELECT A.ID, A.S15, MAX(B.ID) AS MaxID 
    FROM TRELAY AS A 
    INNER JOIN TUSERDEF8 AS B ON A.ID = B.N01 
    WHERE 
    LEFT(A.S15, 1) <> LEFT(B.S04, 1) 
    AND NOT (A.S15 LIKE '%MEDIUM%' AND 
      B.S04 LIKE '%N/A%' AND 
      B.S06 LIKE '%EACMS%') 
    GROUP BY A.ID, A.S15 
) AS C 
INNER JOIN TUSERDEF8 AS D ON C.ID = D.N01 AND C.MaxID = D.ID 
+0

Спасибо. Я думаю, что это будет работать для того, что мне нужно, но что вы подразумеваете под результатом, является двусмысленным? –

+0

@JoeChristou Я имею в виду, что я не уверен, что вы запрашиваете вывод из 1 строки или что-то еще (например, см. Замешательство в комментариях @Dave). Предоставленный вами запрос даст вам 1 строку в качестве вывода, где 'TUSERDEF8.ID' находится на своем текущем максимуме (т. Е. Если этот идентификатор еще не имеет соответствующего отношения, построенного в' TRELAY', то вы получите 0-строчный ответ). Это предполагает целочисленное увеличение TUSERDEF8.ID. Если вам нужна 1 строка каждый раз, когда вы запускаете запрос, вы должны пойти с ответом @ Dave, так как он даст вам последний «TUSERDEF8.ID», который уже имеет все отношения. – Sturgus

+0

О, мои извинения. Я хочу просмотреть все записи TRELAY и сравнить их с последней записью TUSERDEF8.Чтобы дать небольшую предысторию, мы делаем предварительную оценку на каждом устройстве для определения уровня воздействия: низкий, средний или нет, а затем делаем официальную оценку в другой базе данных. Эти результаты отправляются обратно в TUSERDEF8, и я хочу сделать сравнение с последней оценкой (TUSERDEF8), чтобы проверить, соответствуют ли уровни воздействия. Надеюсь, что это объясняет. –

0

Предполагая, что все ваши идентификаторы INT (s), то нижеследующее может работать?

SELECT TOP 1 TRELAY.ID, TRELAY.S15, TUSERDEF8.S04, TUSERDEF8.N01, TUSERDEF8.S06 
FROM TRELAY INNER JOIN TUSERDEF8 
ON TRELAY.ID = TUSERDEF8.N01 
WHERE LEFT(TRELAY.S15, 1) <> LEFT(TUSERDEF8.S04, 1) 
AND NOT (
    TRELAY.S15 LIKE '%MEDIUM%' 
    AND TUSERDEF8.S04 LIKE '%N/A%' 
    AND TUSERDEF8.S06 LIKE '%EACMS%' 
    ) 
ORDER BY TUSERDEF8.ID DESC 

НТН

Dave

+0

Это будет только одна строка, а не верхняя строка для каждой строки 'TRELAY'. –

+1

OK ... не получилось необходимости в каждой строке ... думаю, что CTE от Joe C, вероятно, подходит ... – Dave

+0

Я не уверен, как ваш запрос вернул «Low» в поле TRELAY.S15 , –

0

Вы можете сделать это:

With cteLastRecord As 
(
Select S04, N01, S06, 
     Row_Number() Over (Partition By N01, Order By ID Desc) SortOrder 
    From TUSERDEF8 
) 
SELECT 
    TRELAY.ID, TRELAY.S15, 
    TUSERDEF8.S04, TUSERDEF8.N01, TUSERDEF8.S06 
FROM 
    TRELAY 
INNER JOIN 
    (Select S04, N01, S06 From cteLastRecord Where SortOrder = 1) TUSERDEF8 ON TRELAY.ID = TUSERDEF8.N01 
WHERE 
    LEFT(TRELAY.S15, 1) <> LEFT(TUSERDEF8.S04, 1) 
    AND NOT (TRELAY.S15 LIKE '%MEDIUM%' AND 
      TUSERDEF8.S04 LIKE '%N/A%' AND 
      TUSERDEF8.S06 LIKE '%EACMS%') 
Смежные вопросы