复杂过滤具有多个条件的SQL Server查询

时间:2017-12-04 18:41:37

标签: sql sql-server where

我有一个SQL Server查询,我将几个表连接在一起,我们正在使用SQL Server 2012.我有一个客户编号,客户名称,项目类型,文档编号字段(可以是一个文档编号)我将提到的两个表中的任何一个;即使后面提到了两个字段,我确实希望使用CASE语句将其组合成一个字段),文档数量,文档日期,截止日期,剩余待支付金额,以及描述。

问题是,对于我的项目类型,一个表格(RM20101),不识别与其关联的项目类型,因为该表格中没有项目类型。另一个表(Custom_RecData)识别所有相关文档编号的正确项目类型,但该表仅包含与项目关联的文档编号记录 - 这并非系统中的所有文档编号都有。

所以这里是一个修剪版本的例子:

CUSTNMBR    |  ItemType    |   DocumentNumberRM |  DocNumCUSTOM | DocAmount
------------+--------------+--------------------+---------------+-----------
12345ABC    |  NULL        |   PYMNT01234567    |  NULL         |  - 28.50
12345ABC    |  TOYS        |   9010456778       |  9010456778   |   300.00
12345ABC    |  NULL        |   9010456778       |  NULL         |   300.00
12345ABC    |  NULL        |   9019888878       |  NULL         |    47.90
12345ABC    |  CRAFTS      |   9502345671       |  9502345671   |   145.25
12345ABC    |  NULL        |   9502345671       |  NULL         |   145.25

我将此示例中的列命名为" RM"从RM20101表和" CUSTOM"出来从Custom_RecDate表中走出来。

所以我尝试了很多方法,从CASE语句到我的WHERE子句,到HAVING子句,再到子查询......我无法弄明白。这就是我希望看到的内容:

CUSTNMBR    |  ItemType    |   DocumentNumberRM |  DocNumCUSTOM | DocAmount
------------+--------------+--------------------+---------------+-----------
12345ABC    |  NULL        |   PYMNT01234567    |  NULL         |  - 28.50
12345ABC    |  TOYS        |   9010456778       |  9010456778   |   300.00
12345ABC    |  NULL        |   9019888878       |  NULL         |    47.90
12345ABC    |  CRAFTS      |   9502345671       |  9502345671   |   145.25

那我为什么称这种情况为多?好吧,如果你看看桌子,我会根据以下内容裁掉项目:

  1. 如果ItemTypeDocNumCUSTOM字段都为NULL,则显示它。
  2. 如果ItemType不是NULL并且两个文档编号字段都是非NULL,则显示它。
  3. 如果ItemType为空且DocNumCUSTOM为空,但我们已经看到RM20101 DocumentNumberRM字段中的文档编号(我怀疑会在COUNT或其他东西的HAVING条款中,然后不再显示它。
  4. 如果我找不到第3步的方法,我会得到重复项,如我的初步示例所示。

    我基本上不想复制。我想显示一个项目类型是否为NULL(两个表中的文档编号都不存在)或只显示一次如果Custom_RecDate表中存在,这是唯一一个包含项目类型信息的表。

    这有意义吗?我知道这听起来很复杂,但希望有人能理解这一切。 :)

    谢谢!

    顺便说一下,这里是重要部分(我的查询,尽管这个例子非常简洁):

    SELECT DISTINCT
        R1.CUSTNMBR,
        I.ITMCLSCD AS [ItemType],
        R1.DOCNUMBR AS [DocumentNumberRM],
        I.DOCNUMBR AS [DocNumCUSTOM],
        R1.ORTRXAMT AS [DocAmount]
    FROM
        RM20101 R1
    JOIN 
        RM40401 R2 ON R2.RMDTYPAL = R1.RMDTYPAL
    JOIN 
        RM00401 R3 ON R3.DOCNUMBR = R1.DOCNUMBR
    JOIN 
        RM00101 R4 ON R4.CUSTNMBR = R1.CUSTNMBR
    LEFT OUTER JOIN 
        SR_ITCMCD C ON C.CUSTNMBR = R1.CUSTNMBR
    LEFT OUTER JOIN 
        AR_Description D ON D.SOPNUM = R1.DOCNUMBR
    LEFT OUTER JOIN 
        Custom_RecData I ON I.ITEMNMBR = C.ITEMNMBR 
                         AND I.DOCNUMBR = R1.DOCNUMBR
    

    我再次尝试使用CASE语句并在WHERE条款中加入各种条件,我无法弄清楚。

1 个答案:

答案 0 :(得分:1)

纯粹基于样本数据,MAX()应该可以解决问题:

SELECT
    R1.CUSTNMBR,
    MAX(I.ITMCLSCD) AS [ItemType],
    R1.DOCNUMBR AS [DocumentNumberRM],
    MAX(I.DOCNUMBR) AS [DocNumCUSTOM],
    R1.ORTRXAMT AS [DocAmount]
FROM RM20101 R1
JOIN RM40401 R2 ON R2.RMDTYPAL = R1.RMDTYPAL
JOIN RM00401 R3 ON R3.DOCNUMBR = R1.DOCNUMBR
JOIN RM00101 R4 ON R4.CUSTNMBR = R1.CUSTNMBR
LEFT OUTER JOIN SR_ITCMCD C ON C.CUSTNMBR = R1.CUSTNMBR
LEFT OUTER JOIN AR_Description D ON D.SOPNUM = R1.DOCNUMBR
LEFT OUTER JOIN Custom_RecData I ON I.ITEMNMBR = C.ITEMNMBR 
                                AND I.DOCNUMBR = R1.DOCNUMBR
GROUP BY 
    R1.CUSTNMBR,
    R1.DOCNUMBR,
    R1.ORTRXAMT

删除了DISTINCT GROUP BY,因为MAX()将完成同样的工作,long passengerId = 0; int affectedRows = stmt.executeUpdate(); if (affectedRows == 0) { throw new SQLException("Insert Passenger error: no rows were affected."); } try (ResultSet generatedKeys = stmt.getGeneratedKeys()) { if (generatedKeys.next()) { passengerID = generatedKeys.getLong(1); } else { throw new SQLException("Insert Passenger error: no ID obtained."); } } 需要