检查记录是否在LEFT JOINED表中至少存在一次

时间:2019-10-07 15:26:11

标签: sql-server sql-server-2012

我有一个Images,Orders和OrderItems表,我想匹配任何图像,如果用户已经通过显示 true false 已购买列中。

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

当我使用此案例时,如果我购买的商品有重复,其中已购买 True ,并且重复为 False 。 如果从未购买过该物品,则不会重复,已购买等于 False

----------------------------------
| 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)      |
----------------------------------
| .........................      |
----------------------------------

关于如何将每个图像中的已购买设置为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 个答案:

答案 0 :(得分:1)

您的查询逻辑看起来可疑。看到联接仅由未保留表中的列与参数的比较组成的联接是不寻常的。我怀疑您根本不需要加入用户,因为您似乎专注于某个人“购买”的东西,而不是同一个人“创建”的东西(名称“作者”的暗示)。没有聚合的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示例数据库的-您应该安装该数据库并将其用作学习工具(并有助于使用通用数据源与其他人进行讨论)。请注意,我只是选择了一个随机的客户ID值-您将使用您的参数。我将查询过滤到一系列图像,以简化调试。这些是帮助编写和调试sql的非常简单但有效的方法。