2013-06-27 7 views
1

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

У меня есть 2 таблицы, как это на Msql Server 2008:

Table 1

ProductID, Description, Vendor, Price


Table 2

ProductID, Description, Price

Я хочу, чтобы выбрать все строки из Table 2 и сопоставления данных из Table 1. Но я хочу только вернуть продавца с лучшей ценой (самая низкая цена среди поставщиков) от Table 1, а не у каждого поставщика. Поэтому для любого ProductID в Table 2 должно быть одно совпадение из Table1 или значение NULL, если нет ProductID в Table 1. Я присоединился к таблицам на ProductID и возвратил все нужные мне столбцы, но я не могу заставить его ограничивать только один результат из таблицы 1. Если я делаю это с 1000 строк в Table 2, я должен вернуть 1000 строк. Я заканчиваю с несколькими дополнительными из нескольких совпадений поставщиков.

Результаты должны выглядеть следующим образом:

T1.ProductID, T1.Description, Vendor, T1.Price, T2.ProductID, 
T2.Description, T2.Price, (T2.Price - T1.Price) as 'Amount Saved' 

SQL, я написал довольно просто:

SELECT 
    T1.ProductID, 
    T1.Description, 
    Vendor, 
    T1.Price, 
    T2.ProductID, 
    T2.Description, 
    T2.Price, 
    (T2.Price - T1.Price) AS 'Amount Saved' 

FROM 
    Table2 T2 LEFT OUTER JOIN Table1 T1 
     ON T2.ProductID = T1.ProductID 
ORDER BY T2.ProductID 

Этот ответ от Д. Стэнли работал; с незначительным изменением, чтобы выбрать каждую строку с самой низкой ценой.

SELECT 
    T1.ProductID, 
    T1.Description, 
    T1.Vendor, 
    T1.Price, 
    T2.ProductID, 
    T2.Description, 
    T2.Price, 
    (T1.Price - T2.Price) as 'Amount Saved' 
FROM Table2 T2 
LEFT JOIN (
    SELECT * FROM (
     SELECT ProductID, Description, Vendor, Price, 
     ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY Price ASC) AS Row 
     FROM Table1) as result 
    WHERE row=1 
    ) AS T1 
    ON T2.ProductID = T1.ProductID 
+0

Можете ли вы разместить запрос? –

+1

Что такое «лучшая цена», вы имеете в виду самую низкую (минимальную) цену, максимально сохраненную и т. Д.? вставьте код, который вы попробовали –

ответ

1

Вы можете использовать ROW_NUMBER, чтобы найти «лучший» соответствующий ряд из Table1:

SELECT 
    T1.ProductID, 
    T1.Description, 
    T1.Vendor, 
    T1.Price, 
    T2.ProductID, 
    T2.Description, 
    T2.Price, 
    (T1.Price - T2.Price) as 'Amount Saved' 
    FROM Table2 T2 
    LEFT JOIN (
     SELECT ProductID, Description, Vendor, Price, 
      ROW_NUMBER() OVER (PARTITION BY ProductID ORDER BY Price DESC) Row 
      FROM Table1 
     ) T1 
     ON T2.ProductID = T1.ProductID 
0

Непонятно, что вы имеете в виду под «лучшей ценой». Просто настройте функцию MAX() на функцию MIN(), если это не то, что вы хотите.

SELECT T1.ProductID, T1.Description, Vendor, T1.Price, T2.ProductID, 
T2.Description, T2.Price, (T1.Price - T2.Price) as 'Amount Saved' 
FROM (
SELECT 
ProductID, Vendor, Description, Price 
FROM Table1 t 
WHERE Price = (SELECT MAX(Price) FROM Table1 subT WHERE t.ProductID = subT.ProductID) 
) T1 RIGHT JOIN 
Table2 T2 ON T1.ProductID = T2.ProductID 
  • Here «s то, что вы должны читать.

EDIT: Я прочитал сейчас, что это для SQL Server. Решение, которое я предоставил, и дополнительный материал для чтения работают для SQL Server. Хотя это из руководства MySQL, но есть только стандартный SQL.

0

Даже думал, есть некоторые лучше для предварительной возможности запроса Мне нравится этот путь, если вы хотите включить все возможности с мин стоимости просто удалите внешний запрос.

Если я ошибаюсь в именах таблиц, пожалуйста, дайте мне знать, что я предположил, что вы были , прося, потому что я не уверен на 100%, что вы имеете в виду под «лучшей ценой», но я полагаю, что это был самый низкий из поле «Сохранено количество», которое было выбрано.

SELECT 
    DISTINCT(T1.ProductId) AS ProductId, 
    Description, 
    Vendor, 
    Price, 
    SupplyDescription, 
    SupplyPrice, 
    AmountSaved AS 'Amount Saved' 
FROM 
(
    SELECT 
     T1.ProductId AS ProductId, 
     T1.Description, 
     T2.Vendor, 
     T1.Price, 
    /* T2.ProductId you are joining on this no need to include again*/ 
     T2.Description AS SupplyDescription, 
     T2.Price AS SupplyPrice , 
     (T1.Price - ISNULL(T2.Price,T1.Price)) as AmountSaved 
    FROM 
    Product T1 WITH(NOLOCK) 
    LEFT OUTER JOIN Supply T2 WITH(NOLOCK) 
     ON T1.ProductId = T2.ProductId 
    HAVING T2.Price = MIN(T2.Price) 
) tt 

Примечание: Это предполагает, что таблицы продукты и питания не обновляются динамически в течение дня, или изменяется очень редко, если это не так (продукты и питание таблица обновляется часто) и вы не могли бы оправдать грязные чтения, сделанные, избегая блокировки, просто удалите подсказки WITH(NOLOCK) из запроса