t-sql奇数加入要求

时间:2016-04-15 18:20:02

标签: sql sql-server tsql

很抱歉这个奇怪的标题,但我很难想到更具描述性的东西。

我需要知道如何在T-SQL中完成以下操作:

想象一下,您有以下3个表格,其中包含您对这些实体所期望的典型1对多关系。请注意Items表上的“SpecialBooleanFlag”(稍后会详细介绍):

Customers: CustomerId, CustomerName, (etc....)
Orders:    OrderId, OrderDtm, CustomerId (etc.....)
Items:     ItemId, ItemDescripion, OrderId, **SpecialBooleanFlag**

这听起来像是一个奇怪的要求而且超出我的意思在这篇文章中解释,但想象一下你的老板要求你写一个查询,用他们买过的每件商品都返回了所有客户的完整订单历史记录。但是,如果客户订单的只有一个具有SpecialBooleanFlag = 1的商品,那么使该商品显示为,就像客户在订单中的每个订单上订购商品一样历史。

因此,如果客户从未订购过SpecialBooleanFlag = 1的商品,那么结果数应该等于他们订购商品的总数。但是,如果他们已经下了5个订单并且这些订单中只有一个订单包含SpecialBooleanFlag = 1的项目,则结果计数将为5 + 4,其中4个额外的行将标记的项目与从未真正匹配的4个订单相关联这个项目。

我已经用光标/循环完成了一次,但解决方案太慢了,如果可能的话,我需要知道一种方法来使用普通的旧设置操作。

编辑:例如,想象一下以下查询/结果集:

SELECT CustomerName as Name, CustomerId, OrderId, ItemDescription, SpecialBooleanFlag
FROM Customers C
JOIN Orders O on C.CustomerId = O.CustomerId
JOIN Items I on O.OrderId = I.OrderId
WHERE C.CustomerId = 99

结果:

CustomerName        CustomerId     OrderId      ItemDescription    SpecialBooleanFlag
George Washington   99             1            Shoes              0
George Washington   99             1            Shirt              0
George Washington   99             1            Tie                0
George Washington   99             2            Socks              0
George Washington   99             2            Hat                1     
George Washington   99             2            Bowtie             0
George Washington   99             3            Green Coat         0
George Washington   99             3            Blue Coat          0
George Washington   99             3            Red Coat           0

因此,客户共有3个订单,共有9个项目。帽子虽然是“特别的”,但却是订单#2。我希望它看起来好像每次都要订购。这个结果集是我正在寻找的。帽子出现在订单1和3上,基于它被标记的事实而不是项目与orderId的1和3之间的关联:

 CustomerName        CustomerId     OrderId      ItemDescription    SpecialBooleanFlag
    George Washington   99             1            Shoes              0
    George Washington   99             1            Shirt              0
    George Washington   99             1            Tie                0
    George Washington   99             1            Hat                1 
    George Washington   99             2            Socks              0
    George Washington   99             2            Hat                1     
    George Washington   99             2            Bowtie             0
    George Washington   99             3            Green Coat         0
    George Washington   99             3            Blue Coat          0
    George Washington   99             3            Red Coat           0
    George Washington   99             3            Hat                1 

这更有意义吗?

3 个答案:

答案 0 :(得分:1)

我认为这样的事情应该有效:

app.post('saveFile', function(req, res) {
    fs.writeFile("save.txt", req.body.data, function(err) {
        if(err) {
            return console.log(err);
        }

        console.log("The file was saved!");
        res.end("This message will be sent back to the client!");
    }); 
});

答案 1 :(得分:0)

2个字,交叉申请。

IF OBJECT_ID('tempdb..#Customers') IS NOT NULL DROP TABLE #Customers
IF OBJECT_ID('tempdb..#Orders') IS NOT NULL DROP TABLE #Orders
IF OBJECT_ID('tempdb..#Items') IS NOT NULL DROP TABLE #Items

CREATE TABLE #Customers ( CustomerId INT, CustomerName varchar(255) )
CREATE TABLE #Orders ( OrderId INT, OrderDtm DateTime, CustomerId INT )
CREATE TABLE #Items ( ItemId INT, ItemDescripion VARCHAR(255), OrderId INT, SpecialBooleanFlag BIT )

INSERT INTO #Customers ( CustomerId, CustomerName )
VALUES ( 1,'Customer1' )
,( 2,'Customer2' )
,( 3,'Customer3' )
,( 4,'Customer4' )

INSERT INTO #Orders ( OrderId, OrderDtm, CustomerId )
VALUES (1,'2016-01-01',1)
,(2,'2016-01-02',1)
,(3,'2016-01-03',1)
,(4,'2016-01-04',2)
,(5,'2016-01-05',2)
,(6,'2016-01-06',2)
,(7,'2016-01-07',3)
,(8,'2016-01-08',3)
,(9,'2016-01-09',3)
,(10,'2016-01-10',4)

INSERT INTO #Items ( ItemId, ItemDescripion, OrderId, SpecialBooleanFlag )
VALUES ( 1,'Order1Item1',1,0)
,( 2,'Order1Item2',1,0)
,( 3,'Order1Item3',1,0)
,( 1,'Order2Item1',2,0)
,( 2,'Order2Item2',2,0)
,( 1,'Order3Item1',3,0)
,( 1,'Order4Item1',4,0)
,( 2,'Order4Item2',4,0)
,( 3,'Order4Item3',4,1)
,( 1,'Order5Item1',5,0)
,( 2,'Order5Item2',5,0)
,( 1,'Order6Item1',6,0)

--DECLARE @CustomerId INT = 1 -- no SpecialBooleanFlag
DECLARE @CustomerId INT = 2 -- has SpecialBooleanFlag

SELECT C.CustomerId, C.CustomerName,O.OrderId,O.OrderDtm,I.ItemId,I.ItemDescripion,SpecialBooleanFlag
FROM #Customers C
JOIN #Orders O on C.CustomerId = O.CustomerId
JOIN #Items I on O.OrderId = I.OrderId
WHERE C.CustomerId = @CustomerId
AND SpecialBooleanFlag != 1
UNION
SELECT C.CustomerId, C.CustomerName,O2.OrderId,O.OrderDtm,I.ItemId,I.ItemDescripion,SpecialBooleanFlag
FROM #Customers C
JOIN #Orders O on C.CustomerId = O.CustomerId
JOIN #Items I on O.OrderId = I.OrderId
CROSS APPLY ( SELECT * FROM #Orders O2 WHERE O2.CustomerId = C.CustomerId ) O2
WHERE C.CustomerId = @CustomerId
AND SpecialBooleanFlag = 1

答案 2 :(得分:0)

SELECT  C.CustomerName AS Name,
        C.CustomerId,
        O.OrderId,
        I.ItemDescripion,
        I.SpecialBooleanFlag
FROM    #Customers C
        JOIN #Orders O ON C.CustomerId = O.CustomerId
        JOIN #Items I ON O.OrderId = I.OrderId
WHERE   C.CustomerId = 99
UNION   
SELECT  C.CustomerName AS Name,
        C.CustomerId,
        O.OrderId,
        I.ItemDescripion,
        I.SpecialBooleanFlag
FROM    #Customers C
        JOIN #Orders O ON C.CustomerId = O.CustomerId
        FULL OUTER JOIN #Items I ON I.SpecialBooleanFlag = 1
WHERE   C.CustomerId = 99