【问题标题】:SQL - Select Boolean Results from TableSQL - 从表中选择布尔结果
【发布时间】:2014-05-28 15:03:20
【问题描述】:

好吧,我没有找到这个问题的正确标题,很抱歉。

我有一张表,用于存储发送给用户的一些电子邮件。

在这张表中,我可以知道用户是否阅读了电子邮件。

表结构:

[MAILSEND_ID] (INT),
[ID_USER] (INT), 
[MAIL_ID] (INT), 
[READ] (BIT)

数据:

;WITH cte AS (
SELECT * FROM (VALUES
(1, 10256, 10, 0),
(1, 10257, 10, 1),
(1, 10258, 10, 1),
(1, 10259, 10, 0),
(2, 10256, 10, 0),
(2, 10257, 10, 0),
(2, 10258, 10, 1),
(2, 10259, 10, 0),
(3, 10256, 10, 1),
(3, 10257, 10, 0),
(3, 10258, 10, 0),
(3, 10259, 10, 0)
) as t(MAILSEND_ID, ID_USER, MAIL_ID, READ)

在此示例中,您可以看到,我有 4 个用户和 3 封电子邮件已发送。

User 10256
1st Email - Don't Read
2nd Email - Don't Read
3rd Email - Read

我需要在这个表上做一个选择,我给[MAIL_ID] 和一个[NUMBER],这个数字代表用户没有阅读的连续电子邮件。

使用最后一个例子:

[NUMBER] = 3, [MAIL_ID] = 10

只返回USER_ID 10259

[NUMBER] = 2, [MAIL_ID] = 10

返回USER_ID 10257, 20259.

[NUMBER] = 1, [MAIL_ID] = 10

返回USER_ID 10257, 10258, 20259.

也就是说USER_ID可以有一个累积的未读邮件,但是如果这个用户读了最后一封邮件,他就不能在查询中返回。

这是我今天的查询,但只返回未读邮件的总数:

select * from (
select 
    a.[USER_ID], 
    COUNT(a.[USER_ID]) as tt 
from 
    emailmkt.mailing_history a 
where 
    a.[MAIL_ID] = 58 and 
    a.[READ]=0 
group by 
    [USER_ID]
) aa where tt > [NUMBER]

所以逻辑不对。如果可能的话,我想将此逻辑转移到 SQL,而不是在 Code 上执行此操作。

如果有英文错误也很抱歉。

提前致谢。

【问题讨论】:

  • 那么,mySQL 还是 SQL Server 会是什么?
  • 嗨,Dean,没关系,我需要逻辑。提供的任何查询都会很有用。谢谢。
  • 其实很重要,afaik mySQL 缺少 SQL Server 对窗口函数的支持。
  • 我明白了你所说的,但提供的任何查询都会对我有所帮助。谢谢。

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


【解决方案1】:

通过以下查询,您可以根据 mailsend_id 与时间相关的假设获得用户阅读邮件的滚动计数(我将 READ 更改为 IsRead,因为我的键盘上没有 char `)

SELECT ID_USER, Mail_ID
     , groupid CURRENT
     , @roll := CASE WHEN coalesce(@groupid, '') = groupid 
                     THEN @roll + 1 
                     ELSE 1 
                END AS roll
     , @groupid := groupid OLD
FROM   (SELECT mh.ID_USER, mh.Mail_ID
             , concat(mh.id_user, mh.mail_id) groupid
        FROM mailing_history mh
             INNER JOIN (SELECT   id_user
                                , max(CASE isread 
                                           WHEN 1 THEN MAILSEND_ID 
                                           ELSE 0 
                                      END) lastRead
                         FROM     mailing_history
                         GROUP BY id_user) lr
     ON mh.id_user = lr.id_user AND mh.MAILSEND_ID > lr.lastread
ORDER BY id_user, MAILSEND_ID) a

演示:SQLFiddle

Roll 列包含要为用户阅读的邮件的滚动计数。
添加一个级别,您可以在 WHERE 条件和 group_concat user_id 中根据 NUMBER 检查 Roll 的值

【讨论】:

  • 这段代码非常适合我。我做了一些调整以适应 MS SQL,感谢您的支持。
  • 我为 mysql 编写代码,因为那是之前的标签,在 SQLServer 中更容易,而不是变量 thinghy 使用 ROW_NUMBER() OVER (PARTITION ID_USER, Mail_ID Order By ID_USER, Mail_ID)滚动计数器
猜你喜欢
  • 2020-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-17
相关资源
最近更新 更多