2017-04-21 97 views
0

我在写我的第一个SQL查询,所以请原谅我对此事缺乏了解。通过加入SQL筛选

我正在寻找从每个连接过滤多次,它似乎执行的查询总行增长,而不是收缩。

/* 

Reads Order Status, determines if it's OPEN 
Pulls all OPEN orders to Time Tickets 
Reads the Time Ticket TicketDate, determines if it's > 90 days old 
Compares PODet JobNo, joins PO table 
Reads the PO DateMod, determines if it's > 90 days old 

*/ 


DECLARE @now DATETIME 
DECLARE @90daysago DATETIME 


SET @now = GETDATE() 
SET @90daysago = DATEADD(day, -90, @now) 

SELECT 
    o.JobNo, 
    o.OrderNo, 
    o.PartNo, 
    o.Status, 
    o.JobNo, 
    t.TicketDate, 
    p.Status, 
    p.OutSideService, 
    p.PONum, 
    po.DateEnt, 
    po.DateMod 


FROM 
    RBCBEMD.dbo.OrderDet AS o  /* OrderDet = o */ 

INNER JOIN RBCBEMD.dbo.TimeTicketDet AS t  /* TimeTicket = t */ 
    ON o.JobNo = t.JobNo 

INNER JOIN RBCBEMD.dbo.PODet AS p   /* PODet = p */ 
    ON o.JobNo = p.JobNo 

INNER JOIN RBCBEMD.dbo.PO AS po   /* PO = po */ 
    ON p.PONum = po.PONum 

WHERE 
    o.Status = 'Open' AND 
    t.TicketDate <= @90daysago AND 
    po.DateMod <= @90daysago 

ORDER BY 
    cast(t.TicketDate as DATETIME) DESC 

该查询应该从OrderDet表中找到OPEN订单。从那里,如果它是OPEN,则从TimeTicketDet表中取出最后一个TicketDate。确定TicketDate是否> 90天。如果它大于90天,则从PO表中拉出PONum,找到它的DateMod并确定它是否大于90天。

如果(o.status ='Open')AND(t.ticketDate> 90天大)AND(po.DateMod> 90天大)然后发布JobNo的结果。

+0

我找不到任何错误的查询从快速扫描。它正在做你正在寻找的东西。现在,由于越来越多的门票将超过90天,我希望每次运行它时结果都会增长。你在结果中列出了''''t.ticketDate和po.DateMod''',为什么不检查它们是否每个都超过90天?一个具体的问题对我们帮助你是有帮助的。 – Anand

回答

0

哦,我看这个问题阅读您的需要进行第二次之后。您只想从TimeTicketDet表中取出最后一张票的日期。你需要一个简单的不存在来删除重复行:

DECLARE @now DATETIME 
DECLARE @90daysago DATETIME 

SET @now = GETDATE() 
SET @90daysago = DATEADD(day, -90, @now) 

SELECT 
    o.JobNo, 
    o.OrderNo, 
    o.PartNo, 
    o.Status, 
    o.JobNo, 
    t.TicketDate, 
    p.Status, 
    p.OutSideService, 
    p.PONum, 
    po.DateEnt, 
    po.DateMod 


FROM 
    RBCBEMD.dbo.OrderDet AS o  /* OrderDet = o */ 

INNER JOIN RBCBEMD.dbo.TimeTicketDet AS t  /* TimeTicket = t */ 
    ON o.JobNo = t.JobNo 

INNER JOIN RBCBEMD.dbo.PODet AS p   /* PODet = p */ 
    ON o.JobNo = p.JobNo 

INNER JOIN RBCBEMD.dbo.PO AS po   /* PO = po */ 
    ON p.PONum = po.PONum 

WHERE 
    o.Status = 'Open' AND 
    t.TicketDate <= @90daysago AND 
    po.DateMod <= @90daysago 
and not exists (
    select 1 
    from RBCBEMD.dbo.TimeTicketDet as t2 
    where t2.JobNo = o.JobNo 
    and t2.TicketDate > t.TicketDate 
    ) 

ORDER BY 
    cast(t.TicketDate as DATETIME) DESC 
+0

阿南德 - 我真的很感激。这似乎有窍门,我会做一些研究,找出不存在的条款。我现在看到我有很多专栏的副本,有什么方法可以补救吗?我在线查看了SELECT DISTINCT,但它在我的查询中引发了一个错误。 –

+0

是的,我怀疑你还有重复。不要在这里使用DISTINCT子句。我怀疑发生的情况是您在此处加入了PODet表,并且我怀疑这表示采购订单详细信息,在这种情况下,该采购单中的每个行项目都会重复该工单。如果您想要的只是JobNo,请从选择列表中删除该表格和任何相应的列。 – Anand

+0

如果您需要该表将作业连接到采购订单,则可以使用DISTINCT,但从选择列表中删除可能使该行不同的任何列。 – Anand

0

让我首先回答您的问题:您的表具有一对多或多对多的关系,这会导致重复的行返回。您需要创建表格来排序多对多连接,或者在您的where语句中应用更强大的筛选器以摆脱它们。

如果你看看你的结果,你会看到重复键,大概是这样的:

O.Jobno | P.Status 1 |打开 1 |关闭

请注意您的第一张表(O.Jobno)中的主键将如何多次出现。

这里有一个很好的职位,让你在正确的方向前进: Resolve many to many relationship