SQL查询重复`和`查询,如何避免?

SQL查询重复`和`查询,如何避免?,sql,sql-server,Sql,Sql Server,我有一个疑问: DECLARE @date Date; SET @date = '2020-11-24'; SELECT p.description AS ProductDescription, SUM(CASE WHEN p.code LIKE '%400' THEN requiredQty * 10 WHEN p.code LIKE '%400OL' THEN requiredQty * 10 WHEN

我有一个疑问:

DECLARE @date Date;

SET @date = '2020-11-24';

SELECT p.description AS ProductDescription, 
    SUM(CASE 
            WHEN p.code LIKE '%400' THEN requiredQty * 10
            WHEN p.code LIKE '%400OL' THEN requiredQty * 10
            WHEN p.code LIKE '%396' THEN requiredQty * 6
            WHEN p.code LIKE '%396OL' THEN requiredQty * 6
            WHEN p.code LIKE '%101' THEN requiredQty * 1
            WHEN p.code LIKE '%101OL' THEN requiredQty * 1
            WHEN p.code LIKE '%393OL' THEN requiredQty * 3
        ELSE 0 END) AS RequiredQty,
    '1kg' AS PackSize
FROM SalesOrderLine sol JOIN 
    SalesOrder so
    ON sol.salesOrderID = so.id JOIN
    Product p 
    ON sol.productID = p.id
WHERE 
    p.code like '%396' AND
    so.dueDate = @date
    OR
    p.code like '%396OL' AND
    so.dueDate = @date
    OR
    p.code like '%400' AND
    so.dueDate = @date
    OR
    p.code like '%400OL' AND
    so.dueDate = @date
    OR
    p.code like '%101' AND
    so.dueDate = @date
    OR
    p.code like '%101OL' AND
    so.dueDate = @date
    OR
    p.code like '%393OL' AND
    so.dueDate = @date
GROUP BY p.description;
问题

我多次使用这个
和so.dueDate=@date
来获得准确的数据。如果没有它,我将获得多年前的数据


也许我对这个问题说得太多了?有没有办法避免我一遍又一遍地重复同一个查询?

正如在评论中提到的,您只需要正确封装筛选条件,以便对相关条件进行一次评估并适当组合:

DECLARE @date Date;

SET @date = '2020-11-24';

SELECT p.description AS ProductDescription, 
    SUM(CASE 
            WHEN p.code LIKE '%400' THEN requiredQty * 10
            WHEN p.code LIKE '%400OL' THEN requiredQty * 10
            WHEN p.code LIKE '%396' THEN requiredQty * 6
            WHEN p.code LIKE '%396OL' THEN requiredQty * 6
            WHEN p.code LIKE '%101' THEN requiredQty * 1
            WHEN p.code LIKE '%101OL' THEN requiredQty * 1
            WHEN p.code LIKE '%393OL' THEN requiredQty * 3
        ELSE 0
        END) AS RequiredQty,
    '1kg' AS PackSize
FROM SalesOrderLine sol
    JOIN SalesOrder so
        ON sol.salesOrderID = so.id
    JOIN Product p 
        ON sol.productID = p.id
WHERE (p.code like '%396'
       OR p.code like '%396OL'
       OR p.code like '%400'
       OR p.code like '%400OL'
       OR p.code like '%101'
       OR p.code like '%101OL'
       OR p.code like '%393OL'
      )
   AND so.dueDate = @date
GROUP BY p.description;

从这个查询中,您可能还会发现,通过存储和索引
code
值的反向版本,您可以获得一些性能改进,因此,由于
类似“%val”
的条件,您不会扫描整个表

为了保持代码可读性,您可以像这样应用过滤器:

WHERE (p.codeReverse like reverse('396') + '%'
      etc

您可以通过以下几种方式简化查询:

SELECT p.description AS ProductDescription, 
       SUM(requiredQty * v.factor) as RequiredQty,
       '1kg' AS PackSize
FROM SalesOrderLine sol JOIN 
     SalesOrder so
     ON sol.salesOrderID = so.id JOIN
     Product p 
     ON sol.productID = p.id JOIN
     (VALUES ('%400', 10), ('%400L', 10),
             ('%396', 6), ('%396L', 6),
             ('%101', 1), ('%101L', 1),
             ('%393OL', 3)
     ) v(pattern, factor)
     ON p.code LIKE v.pattern
WHERE so.dueDate = @date
GROUP BY p.description;
JOIN
负责过滤

注意:由于在中多次使用
LIKE
,并且最多有一行匹配,我认为about
JOIN
不会特别昂贵。但是,您可以使用
APPLY
使用
CASE
表达式替换逻辑:

SELECT p.description AS ProductDescription, 
       SUM(requiredQty * v.factor) as RequiredQty,
       '1kg' AS PackSize
FROM SalesOrderLine sol JOIN 
     SalesOrder so
     ON sol.salesOrderID = so.id JOIN
     Product p 
     ON sol.productID = p.id CROSS APPLY
     (VALUES (CASE WHEN p.code LIKE '%400' THEN 10
                   WHEN p.code LIKE '%400OL' THEN 10
                   WHEN p.code LIKE '%396' THEN 6
                   WHEN p.code LIKE '%396OL' THEN 6
                   WHEN p.code LIKE '%101' THEN 1
                   WHEN p.code LIKE '%101OL' THEN 1
                   WHEN p.code LIKE '%393OL' THEN 3
              END)
     ) v(factor)
WHERE so.dueDate = @date AND
      f.factor IS NOT NULL
GROUP BY p.description;

括号-
(A或B或C)和D
-就像许多语言一样,让我们控制AND和OR运算符的组合方式,首先将所有幻数放入一个表中。硬编码会给你带来这样的问题。@Damien_The_unsiver伟大的提示!您可以在中创建一个临时表,其中包含您的选项,并使用“in#tentable”,您的答案的第一部分是可以的。但是带有
反转的第二部分将不起作用。请仔细检查您所写的内容,并再次解释。@SQLPolice确实请添加一些细节,说明您认为这样做行不通的原因。。在您的回答中,突然出现了一个字段“codeReverse”。您没有解释它来自何处以及它包含什么。@SQLPolice是的,我建议创建的字段可以帮助您进行这些搜索:“您还可能发现,通过存储和索引代码值的反向版本,您可以获得一些性能改进。”