1

我试图让这个查询只返回特定用户的最新交易记录,目前我正在使用这个查询,但是它与我不需要的额外信息混淆了。

SELECT TOP 30 
    USER_NAME, 
    CONVERT(nvarchar(20), ACTIVITY_DATE_TIME, 20) AS DATE_TIME, 
    WORK_TYPE, Location, ITEM, Quantity 
FROM 
    TRANSACTION_HISTORY 
WHERE 
    USER_NAME in ('a_user','b_user','c_user','d_user','e_user')
ORDER BY 
    activity_date_time DESC

任何帮助,将不胜感激

4

6 回答 6

1

如果您使用的是 SQL Server 2005 及更高版本(您在这方面不够具体 - 其他 RDBMS 也具有 CTE 和窗口函数等),则一种方法是使用 CTE(公用表表达式ROW_NUMBER) SQL Server 特定功能)。

使用此 CTE,您可以按某些标准(即您的)对数据进行分区,User_Name并让 SQL Server 为每个“分区”从 1 开始为您的所有行编号,并按其他标准(如日期,在您的情况下)排序。

所以尝试这样的事情:

;WITH MostRecentPerUser AS
(
   SELECT 
       USER_NAME, 
       CONVERT(nvarchar(20), ACTIVITY_DATE_TIME, 20) AS DATE_TIME, 
       WORK_TYPE, Location, ITEM, Quantity,
       ROW_NUMBER() OVER(PARTITION BY USER_NAME ORDER BY CAST(ACTIVITY_DATE_TIME AS DATETIME) ) AS 'RowNum'
   FROM 
       dbo.Transaction_History
   WHERE
       USER_NAME in ('a_user', 'b_user', 'c_user', 'd_user', 'e_user')
)
SELECT 
   USER_NAME, 
   DATE_TIME, 
   WORK_TYPE, Location, ITEM, Quantity
FROM 
   MostRecentPerUser 
WHERE
   RowNum = 1

在这里,我只为每个“分区”(即每个User_Name)选择“第一个”条目 - 按Date_Time.

这是否接近你正在寻找的东西?

三旁注:

  • 首先,如果您有一个日期 - 为什么不将其存储为DATETIMEor DATE?应该是——认真的!不要将日期存储为NVARCHAR(20)- 从不!

  • 我会尽量避免使用所有大写的标识符——这些会让你的代码很难阅读和理解。到目前为止,我们已经过了 ALL UPPERCASE 终端——不是吗?

  • 另外:我建议您尝试使用更有意义和更具表现力的名称DATE_TIME- 首先,您有可能与 SQL Server 关键字(如DATETIMEor )发生冲突DATE,其次 - 您应该努力使您的列名(和别名)真正表达他们所代表的——一个SalesDateActivityDate比仅仅更好DATE_TIME

于 2013-05-22T19:54:01.743 回答
1

这将为您提供每个用户的最新活动(假设 ACTIVITY_DATE_TIME 是实际的日期时间字段而不是 varchar 字段)

SELECT 
    USER_NAME, 
    max(ACTIVITY_DATE_TIME) as  ACTIVITY_DATE_TIME
FROM 
    TRANSACTION_HISTORY 
WHERE 
    USER_NAME in ('a_user','b_user','c_user','d_user','e_user')
GROUP BY user_name

如果您有多个相同日期时间的用户(例如,如果您实际上没有存储时间),那么您需要使用 rownumber 来获取一个。

如果您还需要表中的其他列,则将上述查询用作派生表:

SELECT <list the columns you need from theTRANSACTION_HISTORY table >
FROM TRANSACTION_HISTORY th
JOIN (
SELECT 
    USER_NAME, 
    max(ACTIVITY_DATE_TIME) as  ACTIVITY_DATE_TIME
FROM 
    TRANSACTION_HISTORY 
WHERE 
    USER_NAME in ('a_user','b_user','c_user','d_user','e_user')
GROUP BY user_name
) a  On th.USER_NAME = a.USER_NAME  and th. ACTIVITY_DATE_TIME = a. ACTIVITY_DATE_TIME
于 2013-05-22T19:57:10.247 回答
1

我相信用户希望返回IN()子句中每个用户的最新交易。

如果users是一张不同的桌子,我会建议一张桌子JOIN/CROSS APPLY上最近的记录TRANSACTION_HISTORY。但由于它们在同一张桌子上,a 怎么样UNION

SELECT TOP (1) *
FROM TRANSACTION_HISTORY
WHERE USER_NAME = 'a_user'
UNION ALL
SELECT TOP (1) *
FROM TRANSACTION_HISTORY
WHERE USER_NAME = 'b_user'
UNION ALL
SELECT TOP (1) *
FROM TRANSACTION_HISTORY
WHERE USER_NAME = 'c_user'
UNION ALL
SELECT TOP (1) *
FROM TRANSACTION_HISTORY
WHERE USER_NAME = 'd_user'
UNION ALL
SELECT TOP (1) *
FROM TRANSACTION_HISTORY
WHERE USER_NAME = 'e_user'
ORDER BY ACTIVITY_DATE_TIME DESC

这里ORDER BY将适用于整个查询,因为UNION不能对每个人进行排序。

于 2013-05-22T19:41:42.480 回答
1

假设 mssql 2005+,您可以使用 row_number 按用户分区并按活动日期排序。然后你只选择用户的第一行......

SELECT
    *
FROM (
    SELECT
        USER_NAME, 
        CONVERT(nvarchar(20), ACTIVITY_DATE_TIME, 20) AS DATE_TIME, 
        WORK_TYPE, Location, ITEM, Quantity,
        RN = row_number() over(paritition by USER_NAME order by activity_date_time DESC)
    FROM 
        TRANSACTION_HISTORY 
    WHERE 
        USER_NAME in ('a_user','b_user','c_user','d_user','e_user')
) t
WHERE
    t.RN = 1 --only want the top history per user

如果表真的很大,使用 apply 可能会更好,因为看起来您一次只需要为少数用户执行此操作...

 SELECT 
        TTH.* 
    FROM 
        USER U 
        CROSS APPLY (
            SELECT TOP 1
                USER_NAME, 
                CONVERT(nvarchar(20), ACTIVITY_DATE_TIME, 20) AS DATE_TIME, 
                WORK_TYPE, Location, ITEM, Quantity
            FROM 
                TRANSACTION_HISTORY TH
            WHERE
                TH.USER_NAME = U.USER_NAME
            ORDER BY
                activity_date_time DESC
        ) TTH
    WHERE 
        U.USER_NAME in ('a_user','b_user','c_user','d_user','e_user')
于 2013-05-22T19:47:12.070 回答
0

TRANSACTION_HISTORY从具有最新的表中检索记录的所有字段activity_date_time

SELECT * FROM TRANSACTION_HISTORY ORDER BY activity_date_time DESC LIMIT 1;

将 更改为*要检索的字段。

显然,如果您只想检索USER_NAME列具有任何值 的记录('a_user','b_user','c_user','d_user','e_user'),请添加WHERE子句:

SELECT * 
FROM TRANSACTION_HISTORY 
WHERE USER_NAME in ('a_user','b_user','c_user','d_user','e_user')
ORDER BY activity_date_time DESC LIMIT 1;
于 2013-05-22T19:29:06.940 回答
0
SELECT USER_NAME, convert(nvarchar(20),  
ACTIVITY_DATE_TIME, 20) as DATE_TIME, WORK_TYPE, 
Location, ITEM,Quantity 
FROM TRANSACTION_HISTORY WHERE USER_NAME in 
('a_user','b_user','c_user','d_user','e_user')
order by ACTIVITY_DATE_TIME desc LIMIT 1

这有帮助吗?

于 2013-05-22T19:29:53.233 回答