连接表但显示查找表的所有值

时间:2012-02-28 15:54:51

标签: sql sql-server-2008

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

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上的订单进行INNER JOIN,按ORDER.DATE和CardType分组,但它只显示有值的情况,是有一种方法可以使它仍然列出信用卡类型,无论是否有交易或日期订单?只显示该卡类型为零?

真的很感激帮助。

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:1)

我真的只是在这里添加现有的答案,因为答案的第二部分是正确的,但第一部分没有按要求交叉加入,因此省略了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