我正在尝试让此查询仅返回仅针对特定用户的最新事务记录,目前我正在使用此查询,但是它混淆了我不需要的额外信息。
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
任何帮助将不胜感激
答案 0 :(得分:1)
我相信用户希望在IN()
子句中为每个用户返回最新的事务。
如果users
是一个不同的表,我会在JOIN/CROSS APPLY
表中的最新记录上建议TRANSACTION_HISTORY
。但是因为它们在同一个表中,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
个。
答案 1 :(得分:1)
假设mssql 2005+,您可以使用row_number按用户分区并按activity_date排序。然后你只选择用户的第一行......
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')
答案 2 :(得分:1)
一种方法是使用CTE(公用表表达式),如果您使用的是SQL Server 2005及更高版本(在这方面您不够具体 - 其他RDBMS也具有CTE和窗口函数,如{{ 1}} - 那些不是SQL Server特定的功能。)
使用此CTE,您可以按照某些条件对数据进行分区 - 即ROW_NUMBER
- 并为每个“分区”提供从1开始的所有行的SQL Server编号,按其他一些标准排序(如日期,在你的情况下)。
所以尝试这样的事情:
User_Name
在这里,我只选择每个“分区”的“第一个”条目(即每个;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
或DATETIME
?它应该 - 认真!不要将日期存储为DATE
- 永远不要!
我会尽量避免使用所有大写标识符 - 这些会使您的代码难以阅读和理解。我们现在已经超越了ALL UPPERCASE终端 - 不是吗?
另外:我建议尝试使用比NVARCHAR(20)
更有意义且更具表现力的名称 - 首先,您有可能与DATE_TIME
或{DATETIME
之类的SQL Server关键字发生冲突{1}},其次 - 你应该努力让你的列名(和别名)真正表达它们所代表的内容 - DATE
或SalesDate
比ActivityDate
好得多。< / p>
答案 3 :(得分: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
答案 4 :(得分: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;
答案 5 :(得分: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
这有帮助吗?