Проверьте, существуют ли записи хотя бы один раз в таблице LEFT JOINED - PullRequest
0 голосов
/ 07 октября 2019

У меня есть таблица «Изображения», «Заказы» и «OrderItems». Я хочу сопоставить любые изображения, если они уже были куплены пользователем и переданы в качестве параметров с отображением true или false в столбце IsBought .

Select  Images.Id, 
        Images.Title, 
        Images.Description, 
        Images.Location, 
        Images.PriceIT, 
        Images.PostedAt,
        CASE WHEN OrderItems.ImageId = Images.Id THEN CAST(1 AS BIT) 
             ELSE CAST(0 AS BIT) END 
        AS 'IsBought'    
FROM Images
INNER JOIN Users as u on Images.UserId = u.Id

LEFT JOIN Orders on  Orders.UserId = @userId
LEFT JOIN OrderItems on Orders.Id = OrderItems.OrderId and  OrderItems.ImageId = Images.Id

Group By Images.Id, 
            Images.Title, 
            Images.Description, 
            Images.Location, 
            Images.PriceIT, 
            Images.PostedAt,
            OrderItems.ImageId,
            Orders.UserId

Когда я использую этот СЛУЧАЙ, КОГДА У меня есть дубликаты, когда предмет был куплен, где IsBought равно True и дубликат Ложь . В случае, когда Предмет никогда не был куплен, нет дубликатов, IsBought просто равно Ложь

----------------------------------
| User       |  type             |
----------------------------------
| Id         | nvarchar(450)     |
----------------------------------
| .......|
----------------------------------

----------------------------------
| Orders     |  type             |
----------------------------------
| Id         | nvarchar(255)     |
----------------------------------
| UserId     | nvarchar(450)     |
----------------------------------
| ...........................    |
----------------------------------

----------------------------------
| OrderItems |  type             |
----------------------------------
| Id         | nvarchar(255)     |
----------------------------------
| OrderId     | nvarchar(255)    |
----------------------------------
| ImageId    | int               |
----------------------------------

----------------------------------
| Images     |  type             |
----------------------------------
| Id         | int               |
----------------------------------
| UserId     | nvarchar(450)     |
----------------------------------
| Title      | nvarchar(MAX)      |
----------------------------------
| Description| nvarhar(MAX)      |
----------------------------------
| .........................      |
----------------------------------

Любые идеи о том, как я мог простоиметь одну строку на изображения с IsBought , установленным в true или false, но не дубликатов?

Я бы хотел что-то вроде этого:

----------------------------------------------------------------------------
| Id   |  Title  | Description | Location | PriceIT |  Location | IsBought | 
----------------------------------------------------------------------------
| 1   |  Eiffel Tower  | .... | ...... | 20.0      |  Paris     | true    |
----------------------------------------------------------------------------
| 2   |  Tore di Pisa  | .... | ...... | 20.0      |  Italia     | false  |
---------------------------------------------------------------------------
| etc ......
---------------------------------------------------------------------------

1 Ответ

1 голос
/ 07 октября 2019

Логика вашего запроса выглядит подозрительно. Необычно видеть объединение, которое состоит только из сравнения столбца из незарезервированной таблицы с параметром. Я подозреваю, что вам вообще не нужно присоединяться к пользователям, поскольку вы, кажется, сосредоточены на вещах, «купленных» человеком, а не на вещах, «созданных» (что подразумевается под именем «автор») этого же человека. И предложение group by без агрегата часто является сокрытием для логически некорректного запроса.

Так что начните сначала. Вы хотите видеть все изображения по-видимому. Для каждого вы просто хотите узнать, связано ли это изображение с каким-либо порядком данного человека.

select img.*, -- you would, or course, only select the columns needed 

   (select count(*) from Sales.SalesOrderDetail as orddet 
    where orddet.ProductID = img.ProductID) as [Order Count],

   (select count(*) from Sales.SalesOrderDetail as orddet 
    inner join Sales.SalesOrderHeader as ord 
       on orddet.SalesOrderID = ord.SalesOrderID
    where orddet.ProductID = img.ProductID
    and ord.CustomerID = 29620
    ) as [User Order Count], 

    case when exists(select * from Sales.SalesOrderDetail as orddet 
    inner join Sales.SalesOrderHeader as ord 
       on orddet.SalesOrderID = ord.SalesOrderID
    where orddet.ProductID = img.ProductID
    and ord.CustomerID = 29620) then 1 else 0 end as [Has Ordered] 

from Production.ProductProductPhoto as img 
where img.ProductID between 770 and 779
order by <something useful>;

Обратите внимание на псевдонимы - гораздо проще читать длинный запрос, когда вы используете псевдонимы, которые короче, но понятны (т. Е. Не одиночные буквы). Я включил 3 различных подзапроса, чтобы помочь вам понять корреляцию и как вы можете построить свою логику для достижения своей цели и помочь отладить любые проблемы, которые вы обнаружите.

Это основано на примере базы данных AdventureWorks, которую вы должны установить и использовать в качестве учебного пособия (и для облегчения дискуссий с другими людьми с использованием общего источника данных). Обратите внимание, что я просто выбрал случайное значение идентификатора клиента - вы бы использовали свой параметр. Я отфильтровал запрос по диапазону изображений, чтобы упростить отладку. Это очень простые, но эффективные методы, помогающие писать и отлаживать sql.

...