创建SQL查询以按用户检索最新记录
我试图让此查询仅返回特定用户的最新交易记录,目前我正在使用此查询,但它与我不需要的额外信息混淆创建SQL查询以按用户检索最新记录,sql,Sql,我试图让此查询仅返回特定用户的最新交易记录,目前我正在使用此查询,但它与我不需要的额外信息混淆 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',
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
任何帮助都将不胜感激从具有最新活动日期时间的表事务历史中检索记录的所有字段 将*更改为要检索的字段 显然,如果您只想检索USER_NAME列具有来自“a_USER”、“b_USER”、“c_USER”、“d_USER”、“e_USER”中任意一个值的记录,请添加where子句:
从具有最新活动日期时间的表事务\u历史中检索记录的所有字段 将*更改为要检索的字段 显然,如果您只想检索USER_NAME列具有来自“a_USER”、“b_USER”、“c_USER”、“d_USER”、“e_USER”中任意一个值的记录,请添加where子句: 这有用吗
这有帮助吗?我相信用户希望在in子句中返回每个用户的最新事务 如果用户是不同的表,我会建议对TRANSACTION_HISTORY表中的最新记录进行联接/交叉应用。但既然他们都在同一张桌子上,工会怎么样
此处的ORDER BY将应用于整个查询,因为无法对每个工会进行排序。我相信用户希望在in子句中返回每个用户的最新交易 如果用户是不同的表,我会建议对TRANSACTION_HISTORY表中的最新记录进行联接/交叉应用。但既然他们都在同一张桌子上,工会怎么样
此处的顺序将应用于整个查询,因为无法对每个单独的联合进行排序。假设mssql 2005+,您可以使用行编号按用户进行分区,并按活动日期进行排序。然后只选择用户的第一行
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')
假设mssql 2005+,您可以使用行编号按用户划分,按活动日期排序。然后只选择用户的第一行
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')
一种方法是使用CTE公共表表达式,如果您使用的是SQL Server 2005或更高版本,您在这方面不够具体-其他RDBMS也有CTE和窗口功能,如ROW_NUMBER-这些不是SQL Server特有的功能 有了这个CTE,您可以按照一些标准(即用户名)对数据进行分区,并让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
这里,我只为每个分区选择第一个条目,即每个用户名(按日期和时间排序)
这接近你想要的吗
三个旁注:
首先,如果您有一个日期,为什么不将其存储为DATETIME或date?这应该是-认真的!不要将日期存储为NVARCHA20-永远不要
我会尽量避免使用所有大写标识符——这会使您的代码很难阅读和理解。到现在为止,我们已经超过了所有大写的终端,不是吗
另外:我建议尝试使用比DATE_TIME更有意义和表达力的名称-首先,您有可能与SQL Server关键字DATETIME或DATE发生冲突,第二,你应该努力让你的列名和别名真正表达它们所代表的内容——SalesDate或ActivityDate比DATE\u TIME好得多
一种方法是使用CTE公共表表达式,如果您使用的是SQL Server 2005或更高版本,您在这方面不够具体-其他RDBMS也有CTE和窗口功能,如ROW_NUMBER-这些不是SQL Server特有的功能 有了这个CTE,您可以按照一些标准(即用户名)对数据进行分区,并让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
这里,我只为每个分区选择第一个条目,即每个用户名(按日期和时间排序)
这接近你想要的吗
三个旁注:
首先,如果您有一个日期,为什么不将其存储为DATETIME或date?这应该是-认真的!不要将日期存储为NVARCHA20-永远不要
我会尽量避免使用所有大写标识符——这会使您的代码很难阅读和理解。到现在为止,我们已经超过了所有大写的终端,不是吗
另外:我建议尝试使用更有意义的expr
essive名称比DATE_TIME更重要-首先,您有可能与SQL Server关键字如DATETIME或DATE发生冲突,其次-您应该努力使列名和别名真正表达它们所代表的内容-SalesDate或ActivityDate比DATE_TIME好得多
假设activity_DATE_TIME是实际的Datetime字段而不是varchar字段,这将为每个用户获取最新的activity
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来获得一个用户,该用户的instnce具有多个相同的datetime
如果还需要表中的其他列,请将上述查询用作派生表:
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
假设activity_DATE_TIME是实际的Datetime字段而不是varchar字段,这将为每个用户获取最新的activity
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来获得一个用户,该用户的instnce具有多个相同的datetime
如果还需要表中的其他列,请将上述查询用作派生表:
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
如果您只需要一条记录,您可以将top 30更改为top 1,但是您不需要的额外信息是什么?您使用的是哪些rdbms?Transaction_history表的结构是什么?特别是什么是主键?刚才注意到您转换为nvarchar,然后将列命名为DATE\u TIME?这是故意的吗?如果您只需要一条记录,您可以将前30名更改为前1名,但您不需要的额外信息是什么?您使用的是哪些rdbms?事务历史表的结构是什么?特别是什么是主键?刚才注意到您转换为nvarchar,然后将列命名为DATE\u TIME?这是故意的吗?具体的用户怎么办?我认为这些额外的信息是混乱信息的一部分。@ribot你是什么意思?它只是减少了可用行的集合。那么具体的用户呢?它被额外的信息弄糊涂了,我想这是混乱信息的一部分。@ribot你是什么意思?它只是减少了可用行的集合。我仍然使用交叉应用,但只是通过select user_name='a_user'union select'b_user'union select…Nice-没有想到。我仍然使用交叉应用,但只是通过select user_name='a_user'union select'b_user'union select…Nice-没有想到那个