【问题标题】:Joining tables but displaying all the values of a look up table连接表但显示查找表的所有值
【发布时间】:2012-02-28 15:54:51
【问题描述】:

我有一个查表,基本上是信用卡类型

ID |  CCType         |
-----------------------
1  | AMEX            |
2  | VISA            |
3  | MASTER CARD     |
4  | OTHER           |

然后我有另一个包含事务的表,其中 CCTypeID 是查找表中的 ID

TransID   |  CCTypeID   | TransactionName | OrderID |
-----------------------------------------------------
1         | 2           | BILLPAY         |10
2         | 4           | SECUREPAYMENT   |13
3         | 1           | BILLPAY         |15

然后我终于有了另一张订单表

    OrderId | OrderDate   | Product   |   TransID  |
    ------------------------------------------------
    10      |  2012-02-27 |Grapes     | 1
    13      |  2012-02-26 |Wine       | 2
    14      |  2012-01-26 |Pepper     | 6
    15      |  2012-01-26 |Apple      | 1

I want to create a view that looks like this

OrderDate  | CCType      |  Processed
----------- ---------------------------
2012-02-27 | AMEX        |   0
2012-02-27 | VISA        |   1
2012-02-27 | MASTER CARD |   0
2012-02-27 | OTHER       |   0
2012-02-26 | AMEX        |   0
2012-02-26 | VISA        |   0
2012-02-26 | MASTER CARD |   0
2012-02-26 | OTHER       |   1

我已尝试将信用卡类型分别与 CCTypeID 和 ID 上的交易进行右外连接,然后在 ORDERID 上进行订单的内连接,按 ORDER.DATE 和 CardType 分组,但它只显示有值的地方,是有没有办法使它仍然列出信用卡类型,无论该日期是否有交易或订单?只显示该卡类型的零?

非常感谢您的帮助。

【问题讨论】:

  • 您从哪里提取已处理字段?它没有出现在您显示的任何表格中
  • @bluefeet - 这似乎是该日期和卡类型的记录计数。

标签: sql sql-server-2008


【解决方案1】:

您的基本查询应该是这样的......

SELECT
  Orders.OrderDate,
  CardType.CCType,
  COUNT(*)
FROM
  Orders
LEFT JOIN
  Transactions
    ON  Transactions.TransID = Orders.TransID
    AND Transactions.OrderID = Orders.OrderID
LEFT JOIN
  CardType
    ON CardType.ID = Transaction.CCTypeID
GROUP BY
  Orders.OrderDate,
  CardType.CCType

如果您需要“所有日期”来获得值,那么您需要一个额外的表格来加入。例如,创建一个名为calendar 的表并使用您需要的所有日期预先填充它,然后在日期字段上创建一个索引。然后,您可以重新排序查询以强制每个您想要记录的组合...

SELECT
  Calendar.Date,
  CardType.CCType,
  COUNT(Transaction.CCTypeID)
FROM
  Calendar
CROSS JOIN
  CardType
LEFT JOIN
  (
    Transactions
  INNER JOIN
    Orders
      ON  Transactions.TransID = Orders.TransID
      AND Transactions.OrderID = Orders.OrderID
  )
    ON  CardType.ID   = Transactions.CCTypeID
    AND Calendar.Date = Orders.OrderDate
WHERE
  Calendar.Date BETWEEN ??? AND ???
GROUP BY
  Calendar.Date,
  CardType.CCType

【讨论】:

    【解决方案2】:

    我实际上只是在此处添加现有答案,因为答案的第二部分是正确的,但第一部分没有按要求交叉连接,因此省略了 OP 可能需要所有日期的所有卡类型的场景有订单。我不确定这方面的适当礼仪,因为我仍然想利用答案附带的代码格式......

    -- CREATE SAMPLE DATA
    CREATE TABLE #CCType (ID INT NOT NULL PRIMARY KEY, CCType VARCHAR(15) NOT NULL)
    INSERT #CCType VALUES (1, 'AMEX'), (2, 'VISA'), (3, 'MASTER CARD'), (4, 'OTHER')
    CREATE TABLE #Trans (TransID INT NOT NULL PRIMARY KEY, CCTypeID INT NOT NULL, Transactionname VARCHAR(15), OrderID INT NOT NULL)
    INSERT #Trans VALUES (1, 2, 'BIILPAY', 10), (2, 4, 'SECUREPAYMENT', 13), (3, 1, 'BIILPAY', 15)
    CREATE TABLE #Orders (OrderID INT NOT NULL PRIMARY KEY, OrderDate DATETIME NOT NULL, Product VARCHAR(10), TransID INT)
    INSERT #Orders VALUES (10, '20120227', 'Grapes', 1), (13, '20120226', 'Wine', 2), (14, '20120226', 'Pepper', 6), (15, '20120226', 'Apples', 1)
    -- END CREATE SAMPLE DATA
    
    SELECT  OrderDate, 
            CCType, 
            COUNT(CASE WHEN ID = CCTypeID THEN 1 END) [Processed]
    FROM    #CCType, #Orders, #trans
    WHERE   #Orders.TransID = #Trans.TransID
    AND     #Orders.OrderID = #Trans.OrderID
    GROUP BY OrderDate, CCType, ID
    ORDER BY OrderDate DESC, ID
    
    -- DISPOSE OF SAMPLE DATA
    DROP TABLE #Orders, #CCType, #Trans
    

    【讨论】:

    • 不确定是否要在GROUP BY 中添加ID
    • @Dems 只有这样我才能将其包含在ORDER BY 中,因为卡片在问题示例中按 ID 顺序显示。
    猜你喜欢
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 2017-08-30
    • 1970-01-01
    相关资源
    最近更新 更多