2016-09-10 5 views
1

Я изучаю SQL и экспериментирую с SQL Server. У меня две таблицы.Как найти значение MAX из двух таблиц в SQL Server?

Table1

+------+--------+--------+ 
| IDK | CODE | NAME | 
+------+--------+--------+ 
| 1 | 742 | PEN | 
| 2 | 853 | PEN | 
| 3 | 724 | PAPPER | 
| 4 | 544 | PEN | 
| 5 | 451 | PRINTER| 
+------+--------+--------+ 

Table2

+------+--------+ 
| IDK | QTY | 
+------+--------+ 
| 1 | 154 | 
| 2 | 85 | 
| 3 | 74 | 
| 4 | 44 | 
| 5 | 51 | 
+------+--------+ 

Я хочу найти CODE с наивысшим QTY, который имеет название PEN. У меня есть переменная myname = "PEN"

Я пробовал:

SELECT Table1.CODE 
FROM Table1 
INNER JOIN Table2 ON Table1.IDK = Table2.IDK 
WHERE Table2.QTY = (SELECT MAX(Table2.QTY) FROM Table2 WHERE Table1.NAME = :myname) 

Что я должен написать, чтобы вернуть 742?

+0

Вы также можете добавить детали таблицы «MTRDATA», чтобы другие могли понять, что именно вы пытаетесь? – stom

+0

Вы правы, я исправил его сейчас! – John

ответ

1

общих табличных выражений может быть действительно полезным для этого вопроса. «Основная» таблица, которую вы действительно хотите запросить, - это таблицы 1 и 2, соединенные вместе. Поместив это соединение в CTE, мы можем легко его повторно использовать, чтобы получить ответ, который вы ищете.

;WITH cte AS 
(
SELECT t1.IDK, 
     t1.CODE, 
     t1.NAME, 
     t2.QTY 
FROM Table1 t1 
LEFT JOIN Table2 t2 
    ON t1.IDK = t2.IDK 
); 

SELECT t.CODE 
FROM cte t 
WHERE t.NAME = 'PEN' AND 
     t.QTY = (SELECT MAX(QTY) FROM cte WHERE NAME = 'PEN') 
+0

Это сработало! Но вам действительно нужна следующая строка кода: 't.NAME = 'PEN' AND'? – John

+0

@John Да, я считаю, что вам это нужно. Первая часть предложения WHERE ограничивает записи, которые являются перьями, а вторая часть выбирает запись пера с наибольшим количеством всех ручек. –

+0

Хорошо, я согласен, но не включайте его ниже? t.QTY = (SELECT MAX (QTY) FROM cte 'WHERE NAME = 'PEN'') – John

0

Вы можете получить максимум, а затем perorm а JOIN как

select t1.CODE 
from table1 t1 
join (select top 1 IDK from table2 order by QTY desc) xxx 
on t1.IDK = xxx.IDK 
where t1.Name = 'PEN'; 
0

Похоже, вы на правильном пути, и вы должны настроить свой простой запрос, прежде чем перейти к чему-то фантастическому - Бритву Оккама. Вам просто нужно заказать запрос, а затем ограничить количество результатов запроса. Это область, где основные дистрибутивы SQL несовместимы, и я не уверен, что это связано с отсутствием дизайна в спецификации SQL или изгоем языка разработчиками.

В Oracle и Postgres вам понадобится OFFSET и LIMIT, в MySQL вам будет нужен только LIMIT, а с IBM DB2 вы будете использовать FETCH FIRST, все они расположены ближе к концу запроса. При использовании T-SQL (для MS SQL Server) вы будете использовать TOP в SELECT.

DECLARE @myname VARCHAR(32) = 'PEN' 

SELECT TOP 1 
    t1.CODE 
FROM Table1 t1 
INNER JOIN t2 
ON t1.IDK = t2.IDK 
WHERE t1.NAME = @myname 
ORDER BY t2.QTY 

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

Кроме того, избегайте вложенных запросов, когда они не нужны для удобочитаемости, ремонтопригодности и производительности. Каждый уровень вложенности добавляет измерение к объему обрабатываемых данных, а время запроса имеет соотношение 1: 1 и объем данных. В этом случае вложенность и JOINing окажут такое же влияние на размер данных, но вложенность исключает возможность оптимизации некоторых баз данных. Обе эти стратегии превосходны в правильных целях, но, как кто-то учится, убедитесь, что вы понимаете их обоих, прежде чем становиться зависимыми от них.

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