如何根据用户ID的联系人表限制对查询行的访问

时间:2011-11-19 14:23:28

标签: mysql

我有一个产生如下结果的查询:

desired output

数据按日期DESC排序,然后按时间DESC排序,但常见的'markers_name'元素也被排在一起。 (他们每个日期只是在一起)。

要执行此操作,我会在MAX(time)中获取(markers_id, date)的每个组合的conditions值列表,然后将该列表加入我从当前查询中获取的行集,并且使用MAX(time)值进行排序:

SELECT
  m.name AS markers_name,
  c.time AS conditions_time,
  c.date AS conditions_date,
  s.name AS station_name
FROM markers m
  INNER JOIN conditions c ON c.markers_id = m.id
  INNER JOIN station s    ON c.station_id = s.id
  INNER JOIN (
    SELECT
      markers_id,
      date,
      MAX(time) AS time
    FROM conditions
    GROUP BY
      markers_id,
      date
  ) mx ON c.markers_id = mx.markers_id AND c.date = mx.date
ORDER BY
  c.date DESC,
  mx.time DESC,
  m.name DESC,
  c.time DESC

现在我需要限制用户访问某些行。
条件表有一个“私有”列。如果'private'设置为1,则只允许某些人查看查询行。可以看到它的人包括创建条件报告的人和该人的联系人。条件表具有'user_id',其中包含创建条件报告的人员的ID。联系人是从“联系人”表中获得的,该表有两个字段:“user_id”和“friend_id”。我有请求信息的人的user_id。

要重申另一种方式,我需要做这样的事情:

  1. 执行上述查询,还要检查c.private是否设置为1。
  2. 如果将c.private设置为1,请使用c.user_id从contacts表中获取该用户的'friend_id。
  3. 如果请求信息的人的user_id与c.user_id或c.user_id的任何朋友匹配,则返回查询行。如果没有,请不要返回该行或返回指示该行是私有的内容(例如,我可以在数据库中使用名为“Private”的markers_name。
  4. 如果有人有任何想法,我很乐意听到。昨天我一整天都在挣扎。谢谢。

2 个答案:

答案 0 :(得分:1)

可能只是添加这样的过滤器就足够了:

…
WHERE c.Private <> 1
   OR c.user_id = @user_id
   OR c.user_id IN (
     SELECT friend_id
     FROM contacts WHERE user_id = @user_id
   )

其中@user_id是请求信息的人的ID。

这会禁止私有行出现在不合适的输出中。

但是,如果您希望他们在那里,但被标记为Private(稍后在客户端或类似的事情中处理),您可以将该过滤器用作您的列SELECT子句:

SELECT
  NOT (
    c.Private <> 1
    OR c.user_id = @user_id
    OR c.user_id IN (
      SELECT friend_id
      FROM contacts WHERE user_id = @user_id
    )
  ) AS IsPrivate,
  …
FROM …

答案 1 :(得分:1)

我没有类似的桌子可以玩,所以我写这个给你试试,好吧?以下是您要添加到查询中的WHERE子句:

WHERE
    -- all non-1 valued `private` columns are public, right? remove if not
    c.private <> 1 
    -- all private but @user_id is entitled to view
    OR (
        c.private = 1 
        AND (
             (c.user_id = @user_id) -- requestor is creator
             OR (
                 EXISTS (
                     SELECT ct.friend_id 
                     FROM contacts ct
                     WHERE ct.user_id = c.user_id
                     AND friend_id = @user_id
                 ) -- requestor is a friend of the creator
                )
            )
       )

再一次,我无法测试这个......我现在就把它留给你了..所以请让我知道它是怎么回事。 :)