使用max(列)和另一列> 0连接表

时间:2015-11-20 15:35:34

标签: sql sql-server sql-server-2008 tsql

我有两张桌子,我正在尝试为我们的筹款部门建立一个查询,但我正在努力。使用SQL Server 2008。

上诉表中包含有关我们将向哪些成员发送捐款申诉的数据。

Yearly_Gift表包含会员每年捐赠多少钱的数据。有时这个表可以在特定年份内获得零美元金额。

我正在尝试做的是使用这两个表来提出去年有人捐赠的内容以及他们捐赠的金额,只要它大于零,我们发出的申诉就是这样。

以下是表格和一些数据的简化版本。我也包括我想要的输出。任何人都可以帮我这个吗?

--Build Tables

CREATE TABLE [dbo].[Appeals](
    [Appeal_ID] [int] NOT NULL,
    [Member_ID] [int] NOT NULL,
 CONSTRAINT [PK_Appeals] PRIMARY KEY CLUSTERED 
(
    [Appeal_ID] ASC,
    [Member_ID] ASC
)WITH (PAD_INDEX  = OFF, 
STATISTICS_NORECOMPUTE  = OFF, 
IGNORE_DUP_KEY     =     OFF, 
ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]


CREATE TABLE [dbo].[Yearly_Gift](
    [Member_ID] [int] NOT NULL,
    [FiscalYear] [char](4) NOT NULL,
    [Amount] [money] NULL,
 CONSTRAINT [PK_Yearly_Gift] PRIMARY KEY CLUSTERED 
(
    [Member_ID] ASC,
    [FiscalYear] ASC
)WITH (PAD_INDEX  = OFF, 
 STATISTICS_NORECOMPUTE  = OFF, 
 IGNORE_DUP_KEY =     OFF, 
 ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]


--Fill tables

INSERT INTO Appeals VALUES (1,101)
INSERT INTO Appeals VALUES (1,102)
INSERT INTO Appeals VALUES (2,101)
INSERT INTO Appeals VALUES (2,102)
INSERT INTO Appeals VALUES (2,103)
INSERT INTO Appeals VALUES (2,104)
INSERT INTO Appeals VALUES (2,105)

INSERT INTO Yearly_Gift VALUES(101,'2015',100)
INSERT INTO Yearly_Gift VALUES(102,'2014',0)
INSERT INTO Yearly_Gift VALUES(102,'2012',150)
INSERT INTO Yearly_Gift VALUES(102,'2011',200)
INSERT INTO Yearly_Gift VALUES(103,'2013',500)
INSERT INTO Yearly_Gift VALUES(103,'2014',500)
INSERT INTO Yearly_Gift VALUES(104,'2012',200)
INSERT INTO Yearly_Gift VALUES(104,'2015',100)

所需输出

Appeal_ID  Member_ID  FiscalYear  Amount
2          101         2015       100
2          102         2012       150
2          103         2014       500   
2          104         2015       100 
2          105         NULL       NULL  

感谢您提供任何帮助。

5 个答案:

答案 0 :(得分:0)

WITH X AS
(
    SELECT A.[Appeal_ID], A.[Member_ID],Y.[FiscalYear], Y.[Amount] 
    FROM [dbo].[Appeals] A
    LEFT JOIN [dbo].[Yearly_Gift] Y ON Y.[Member_ID] = A.[Member_ID]
)
SELECT X.[Appeal_ID], X.[Member_ID],Y.[FiscalYear], X.[Amount] 
FROM X
LEFT JOIN (
    SELECT [Member_ID], 
    MAX([FiscalYear]) AS [FiscalYear] , 
    MAX([Appeal_ID]) AS [Appeal_ID]
    FROM X 
    WHERE Amount > 0
    GROUP BY X.[Member_ID]
) Y ON X.Appeal_ID = Y.Appeal_ID AND X.Member_ID = Y.Member_ID AND X.FiscalYear = Y.FiscalYear
WHERE Y.[FiscalYear] IS NULL AND  X.[Amount]  IS NULL OR Y.[FiscalYear] IS NOT NULL AND  X.[Amount]  IS NOT NULL
ORDER BY X.Appeal_ID,X.Member_ID

答案 1 :(得分:0)

试试这个

  Select a.Appeal_ID, a.Member_ID, y.FiscalYear, y.Amount
  From Appeals a INNER JOIN Yearly_Gift y ON a.Member_ID = y.Member_ID
  where y.Amount > 0 AND y.FiscalYear = 2014

答案 2 :(得分:0)

with cte as (
     SELECT Appeal_ID,  A.Member_ID,  FiscalYear,  Amount,
            row_number() over (partition by A.Member_ID order by FiscalYear  DESC) as rn
     FROM Appeals A
     LEFT JOIN Yearly_Gift Y  
            ON A.Member_ID = Y.Member_ID
)
SELECT *
FROM cte
WHERE rn = 1
  AND Amount <> 0

答案 3 :(得分:0)

嗯 - 这个查询有点长/丑,但它有效。如果我有更多时间,我会研究优化和代码减少。

SELECT
  target_members.Appeal_ID, target_members.Member_ID, FiscalYear, Amount
FROM
  (
    SELECT
      MAX( Appeal_ID ) AS Appeal_ID,
      Member_ID
    FROM
      Appeals
    GROUP BY
      Member_ID
  ) AS target_members
  LEFT OUTER JOIN (
    SELECT
      MAX( Appeals.Appeal_ID ) AS Appeal_ID,
      Yearly_Gift.Member_ID,
      Yearly_Gift.FiscalYear,
      Yearly_Gift.Amount,
      ROW_NUMBER() OVER ( PARTITION BY Yearly_Gift.Member_ID ORDER BY FiscalYear DESC ) AS r
    FROM
      Appeals,
      Yearly_Gift
    WHERE
      Yearly_Gift.Member_ID = Appeals.Member_ID AND
      Amount > 0
    GROUP BY
      Yearly_Gift.Member_ID,
      Yearly_Gift.FiscalYear,
      Yearly_Gift.Amount
  ) AS last_donation
  ON last_donation.Appeal_ID = target_members.Appeal_ID AND
     last_donation.Member_ID = target_members.Member_ID AND
     r = 1

答案 4 :(得分:0)

      SELECT  MAX(A.APPEAL_ID),  A. MEMBER_ID, B. FISCAL_YEAR,B.AMOUNT
      FROM XX_APPEALS A  LEFT OUTER JOIN
       (
         SELECT Y.MEMBER_ID, Y.FISCAL_YEAR, Y.AMOUNT
         FROM XX_YEARLY_GIFT Y, -- select all columns in yearly_gift
           (                    -- that match the latest year per member
            SELECT MEMBER_ID, MAX(FISCAL_YEAR) LATEST_YEAR
            FROM XX_YEARLY_GIFT
            GROUP BY MEMBER_ID  --find latest year of giving per member
            ) S
           WHERE Y.MEMBER_ID = S.MEMBER_ID
           AND Y.FISCAL_YEAR = S.LATEST_YEAR
           ORDER BY Y.MEMBER_ID   
         ) B
     ON  A.MEMBER_ID = B.MEMBER_ID
     GROUP BY A. MEMBER_ID, B. FISCAL_YEAR,B.AMOUNT
     ORDER BY A.MEMBER_ID

这也可以用来报告最大礼物而不是最近的礼物,或者报告最近和最近的年份,以及large_gift。