【问题标题】:Currently using multiple left joins in SQL Server - is there an easier way?目前在 SQL Server 中使用多个左连接 - 有没有更简单的方法?
【发布时间】:2015-12-29 13:43:45
【问题描述】:

我有一个 SQL 语句可以产生正确的结果,但是该语句很长并且可能格式不正确。有人对缩短语句有什么建议吗?

SELECT 
    COUNT(b.priceRRP) AS tomi, 
    COUNT(c.priceRRP) AS mac, 
    COUNT(d.priceRRP) AS well, 
    COUNT(bt.priceTrade) AS tomiTrade, 
    COUNT(ct.priceTrade) AS macTrade, 
    COUNT(dt.priceTrade) AS wellTrade
FROM 
    Items AS a
RIGHT JOIN 
    PriceT AS pt ON pt.internalid = a.internal_id
LEFT JOIN 
    Pricewell AS d ON d.idn = (SELECT TOP(1) idn FROM Pricewell 
                               WHERE pt.idn = item 
                                 AND CASE WHEN a.taxcode = 1 THEN a.retailPrice 
                                          ELSE a.retailPrice * 1.2 END > priceRRP 
                                 AND priceRRP <> 0 
                                 AND syncDate = '2015-10-01' 
                               ORDER BY syncDate DESC, syncTime DESC)
LEFT JOIN 
    Pricetomi AS b ON b.idn = (SELECT TOP(1) idn FROM Pricetomi 
                               WHERE pt.idn = item 
                                 AND CASE WHEN a.taxcode = 1 THEN a.retailPrice 
                                          ELSE a.retailPrice * 1.2 END > priceRRP 
                                 AND priceRRP <> 0 
                                 AND syncDate = '2015-10-01' 
                               ORDER BY syncDate DESC, syncTime DESC)
LEFT JOIN 
    Pricemac AS c ON c.idn = (SELECT TOP(1) idn FROM Pricemac 
                              WHERE pt.idn = item 
                                AND CASE WHEN a.taxcode = 1 THEN a.retailPrice 
                                         ELSE a.retailPrice * 1.2 END > priceRRP 
                                AND priceRRP <> 0 
                                AND syncDate = '2015-10-01' 
                              ORDER BY syncDate DESC, syncTime DESC)
LEFT JOIN 
    Pricewell AS dt ON dt.idn = (SELECT TOP(1) idn FROM Pricewell 
                                 WHERE pt.idn = item 
                                   AND CASE WHEN a.taxcode = 1 THEN a.tradePrice 
                                            ELSE a.tradePrice * 1.2 END > priceTrade 
                                   AND priceTrade <> 0 
                                   AND syncDate = '2015-10-01' 
                                 ORDER BY syncDate DESC, syncTime DESC)
LEFT JOIN 
    Pricetomi AS bt ON bt.idn = (SELECT TOP(1) idn FROM Pricetomi 
                                 WHERE pt.idn = item 
                                   AND CASE WHEN a.taxcode = 1 THEN a.tradePrice 
                                            ELSE a.tradePrice * 1.2 END > priceTrade 
                                   AND priceTrade <> 0 
                                   AND syncDate = '2015-10-01' 
                                 ORDER BY syncDate DESC, syncTime DESC)
LEFT JOIN 
    Pricemac AS ct ON ct.idn = (SELECT TOP(1) idn FROM Pricemac 
                                WHERE pt.idn = item 
                                  AND CASE WHEN a.taxcode = 1 THEN a.tradePrice 
                                           ELSE a.tradePrice * 1.2 END > priceTrade 
                                  AND priceTrade <> 0 
                                  AND syncDate = '2015-10-01' 
                                ORDER BY syncDate DESC, syncTime DESC)
WHERE 
    a.inactive = 0
    AND a.discontinued = 0

谢谢 克里斯

【问题讨论】:

  • 好吧,我看到很多查询,但我会保存这个;)
  • 查询看起来很糟糕:)
  • 这是一个为写作而构建的 OLTP 数据库模式。绝对不读书。我看不出你对Pricewell 的两次加入有什么不同。它们看起来像同一个连接。
  • 嗨,尼克,联接会根据 priceTrade 和 priceRRP 略有变化。克里斯
  • 现在我明白了。接下来是您限制为单个syncDate,然后按它订购。这只是为了说明吗?这些Top 1 Order by 连接很难获得良好的性能。因此,您遇到了性能问题,还是只想知道查询是否可以用不同的方式编写?

标签: sql-server left-join


【解决方案1】:

我认为你不能缩短这么多。请注意,您可以为此使用outer apply

SELECT ...
FROM PriceT AS pt
LEFT JOIN Items AS a ON pt.internalid = a.internal_id
OUTER APPLY (SELECT TOP(1) priceRRP FROM Pricewell ...) d
OUTER APPLY (SELECT TOP(1) priceRRP FROM Pricetomi ...) b
...
WHERE ...

还有很多人发现使用left join 而不是right join 更容易理解。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    相关资源
    最近更新 更多