2012-09-18 195 views
3

我有一个select语句,并且只有当其中至少有一个与今天有60天不同的日期时才返回所有值。 问题是我有一个外部应用程序,它返回我想要比较的列,它们来自不同的表(一个属于现金项目,另一个属于卡项目)。
考虑到我有以下几点:仅当至少有一行匹配时才选择条件

OUTER APPLY (
    SELECT COUNT(*) AS quantity, MIN(date) AS item_date 
     FROM dbo.get_cash_items(loans.id_cash) AS cash_item 
     HAVING loans.id_product_type = 1 --Cash 
    UNION 
    SELECT COUNT(*) AS quantity, MIN(date) AS item_date 
     FROM dbo.get_card_items(loans.id_card) AS card_item 
     HAVING loans.id_product_type = 2 --Card 
) AS items 

我想返回所有的行,只有当DATEDIFF(DAY, MIN(items.item_date), GETDATE()) >= 60,但我想他们都哪怕只有一个匹配这个条件。
这样做的最佳方法是什么?

编辑
使其更清晰,我将解释使用案例:
我需要显示每一笔贷款的项目,只有当客户端是在到期日上的60多天晚任何它

+0

你确定要使用'UNION'而不是'UNION ALL'吗? – Kermit

+0

这也是一样的,我会根据loans.id_product_type获取物品,它总是会是一个或另一个(没有联盟真的发生)。 –

+2

我明白了。 ** ** **强烈建议您始终使用'UNION ALL',除非您需要删除重复项。由于引擎跳过检查重复项的额外步骤,因此速度要快得多。 – Kermit

回答

1

我也不太清楚,你能指望什么,而是怎么样:

WITH items 
    AS (SELECT Count(*) AS quantity, 
       Min(date) AS item_date 
     FROM dbo.Get_cash_items(loans.id_cash) AS cash_item 
     HAVING loans.id_product_type = 1 
     UNION 
     SELECT Count(*) AS quantity, 
       Min(date) AS item_date 
     FROM dbo.Get_card_items(loans.id_card) AS card_item 
     HAVING loans.id_product_type = 2) 
SELECT a.* 
FROM items AS a, 
     (SELECT TOP 1 * 
     FROM items AS b 
     WHERE Datediff(day, b.item_date, Getdate()) >= 60) AS c 

它是一种CROSS JOIN的,在表C都会有一个或零行取决于是否条件满足 - 它会加入到其他表中的每一行。

+0

这正是我所需要的。谢谢。 –

0

你有没有尝试过这样的事情?

SELECT a.quantity, a.item_date 
FROM 
    (SELECT COUNT(*) AS quantity, MIN(date) AS item_date 
     FROM dbo.get_cash_items(loans.id_cash) AS cash_item 
     HAVING loans.id_product_type = 1 
    UNION 
    SELECT COUNT(*) AS quantity, MIN(date) AS item_date 
     FROM dbo.get_card_items(loans.id_card) AS card_item 
     HAVING loans.id_product_type = 2) a 
WHERE DATEDIFF(day, a.item_date, GETDATE()) >= 60 
+0

这只会返回符合条件的行。 –

+0

@PabloMartínez您能向我们展示一些具有期望结果的样本数据吗? – Kermit

+0

我编辑了我的答案。如果一行符合我写的条件,我需要获得所有的行,否则都不行。 –

0

通常我使用CTE来选择我想要选择的记录的关键字,然后加入。下面是一个例子尝试:

with LateClients as 
(
    SELECT LoadId FROM Payment Where /*payment date later than 60 days*/ 
) 

SELECT  p.LoanId, 
      p.UserId 
FROM  Payment as p 
INNER JOIN LateClients as LC 
ON   p.LoanId = lc.LoanId 
OrderBy p.LoanId, p.UserId 

我知道这是从你们发布的代码有点不同,但是这是要解释这个概念一个简单的例子。祝你好运!

+0

这只会带来日期晚于60天的付款,而且我希望所有付款即使其中只有一个是最后一天。 @WojtusJ的解决方案可以做到这一点。 –

+0

我不知道你的表格是如何构建的,所以我不能说这是否属实。我可以说的是,如果您的付款表具有LoanId列,那么上述查询将为特定贷款带来所有付款,如果该贷款的付款时间晚于60天。它不仅会选择延迟付款。 –

相关问题