如果另一列为每个字段为空,则按一列排序

时间:2011-10-01 10:03:21

标签: mysql sql sql-order-by

我有两个表:一个主题表和一个连接的注释表,两个都有时间戳列。我想订购主题列表,以便最新评论的主题位于顶部。但是,如果主题没有注释,我希望它按创建日期排序。 换句话说,我正在尝试对它进行排序,以便主题按创建日期排序如果没有评论 - 基本上就像任何论坛一样。例如,如果主题A(空)在主题B(非空)之后创建但主题B有最近的回复,则订单应为B,A。我不希望所有空如果它们是旧的则位于顶部或如果它们是新的则位于底部。

我尝试了IF ISNULL语句,但是它适用于整个列,而不是每一行,所以我最终将空心线卡在了Feed的顶部或底部。

我猜我必须构建一个只包含每个主题的最新评论的虚拟列...?

以下是完整的陈述:

SELECT
  $showbody,
  Topics.Title,
  Topics.id AS tID,
  Topics.Timestamp,
  Topics.MemberID,
  Users.id,
  Users.FirstName,
  Users.LastName,
  GROUP_CONCAT(DISTINCT Tags.Keywords SEPARATOR ', ') AS Tags,
  COUNT(Comments.id) AS NumberOfComments,
  (
    SELECT COUNT(Comments.id)
    FROM Comments
      LEFT JOIN Views ON Comments.TopicID = Views.TopicID
    WHERE Comments.Timestamp > Views.Visited
  ) AS NewComments
FROM Topics 
  LEFT JOIN Users ON Topics.MemberID = Users.ID 
  LEFT JOIN Comments ON Topics.id = Comments.TopicID 
  LEFT JOIN Tags ON Topics.id = Tags.TopicID 
WHERE Topics.id NOT IN (
  SELECT Tags.TopicID
  FROM Tags
  WHERE Keywords IN (
    SELECT Tag
    FROM Filters
    WHERE MemberID = '$_SESSION[SESS_MEMBER_ID]'
  )
  GROUP BY Tags.TopicID
) 
GROUP BY Topics.id 
ORDER BY Comments.Timestamp, Topics.Timestamp DESC LIMIT $plim

非常感谢任何帮助

2 个答案:

答案 0 :(得分:2)

使用左连接作为评论,对主题进行分组,使用max获取上次评论的时间,并使用coalesce(或isnull)对评论日期进行排序(如果它在那里)和创建否则。否则。

示例:

select t.Title, t.CreatedDate, max(c.CreatedDate) as LastComment
from Topics t
left join Comment c on c.TopicId = t.TopicId
group by t.Title, t.CreatedDate
order by coalesce(max(c.CreatedDate), t.CreatedDate) desc

答案 1 :(得分:2)

解决方案1(演示):

-- Test initialization
CREATE TABLE Question
(
     QuestionID INT AUTO_INCREMENT PRIMARY KEY
    ,Content NVARCHAR(100) NOT NULL
    ,CreateDate DATETIME NOT NULL -- DEFAULT NOW()
);

CREATE TABLE QuestionComment
(
     QuestionCommentID INT AUTO_INCREMENT PRIMARY KEY
    ,QuestionID INT NOT NULL REFERENCES Question(QuestionID)
    ,Content NVARCHAR(100) NOT NULL
    ,CreateDate DATETIME NOT NULL -- DEFAULT NOW()
);

INSERT  Question(Content, CreateDate)
SELECT  'Question 1','2011-01-01 01:00:00'
UNION ALL
SELECT  'Question 2','2011-01-01 02:00:00'
UNION ALL
SELECT  'Question 3','2011-01-01 03:00:00';

INSERT  QuestionComment(QuestionID, Content, CreateDate)
SELECT  1,'Comment 1.1','2011-01-01 01:30:00'
UNION ALL
SELECT  2,'Comment 2.1','2011-01-01 02:30:00'
UNION ALL
SELECT  1,'Comment 1.2','2011-01-01 02:40:00'
UNION ALL
SELECT  2,'Comment 2.2','2011-01-01 02:30:00'
UNION ALL
SELECT  1,'Comment 1.3','2011-01-01 03:30:00';
-- End of Test initialization

-- Solution
SELECT  *
FROM    Question q
LEFT JOIN
(
    SELECT  qc.QuestionID, MAX(qc.CreateDate) LastCreateDate
    FROM    QuestionComment qc
    GROUP BY qc.QuestionID
) qc    ON q.QuestionID=qc.QuestionID
ORDER BY IFNULL(qc.LastCreateDate, q.CreateDate) ASC;
-- End of Solution

-- By, by
DROP TABLE QuestionComment;
DROP TABLE Question;

结果:

2   Question 2  2011-01-01 02:00:00 2   2011-01-01 02:30:00
3   Question 3  2011-01-01 03:00:00     
1   Question 1  2011-01-01 01:00:00 1   2011-01-01 03:30:00

解决方案2:

SELECT  *
FROM    Topics t
LEFT JOIN
(
    SELECT  c.TopicID, MAX(Timestamp) LastTimestamp
    FROM    Comments c
    GROUP BY c.TopicID 
) c ON t.id = c.TopicID 
ORDER BY IFNULL(c.LastTimestamp, t.Timestamp) ASC