查询以从新闻提要中获取评论

时间:2018-10-09 13:18:39

标签: mysql sql join subquery correlated-subquery

一旦某人发布新闻源以及其他用户成为朋友,则必须同时选择此人及其朋友的新闻源 根据他/她是否是朋友的检查,必须选择对新闻提要的评论

这是我的下表结构 enter image description here

以下查询成功地从该人以及该人的朋友那里获取了具有有效用户名和用户照片的新闻提要

$data = $this->db->query("
SELECT DISTINCT(ft.ID) as ID, ft.userid, ft.content, ft.timestamp, 
                ft.likes, ft.comments, u.username, u.avatar 
    FROM feed_item ft, users u 
    WHERE ft.userid = u.ID AND ft.userid 
    IN 
    (SELECT u.ID 
     FROM users u 
     WHERE 
        u.ID IN (SELECT uf.friendid FROM user_friends uf WHERE uf.status = '2' AND uf.userid = '".$this->user->info->ID."') 
     OR u.ID IN (SELECT uf.userid FROM user_friends uf WHERE uf.status = '2' AND uf.friendid = '".$this->user->info->ID."')
     OR u.ID = '".$this->user->info->ID."'
    ) 
ORDER BY ft.ID DESC")->result_array();

但是当我修改查询以仅从该人的朋友那里检索所有评论时。

这导致用户名和用户的照片的值为空

$data = $this->db->query("
SELECT DISTINCT ft.ID as ID, ft.userid, ft.content, ft.timestamp, 
       ft.likes, ft.comments, ftc.comment, u.username, u.avatar 
FROM  feed_item_comment ftc
LEFT JOIN feed_item ft 
  ON ftc.postid = ft.ID 
 AND ftc.userid != '".$this->user->info->ID."' AND ftc.userid = ft.userid
LEFT JOIN user_friends uf 
  ON uf.friendid = ftc.userid 
LEFT JOIN users u 
  ON u.ID = uf.friendid 
 AND ft.userid  IN 
(SELECT u.ID 
 FROM users u 
 WHERE 
    u.ID IN (SELECT uf.friendid FROM user_friends uf WHERE uf.status = '2' AND uf.userid = '".$this->user->info->ID."') 
 OR u.ID IN (SELECT uf.userid FROM user_friends uf WHERE uf.status = '2' AND uf.friendid = '".$this->user->info->ID."')
 OR u.ID = '".$this->user->info->ID."'
) 
ORDER BY ft.ID DESC")->result_array();

我应该如何针对第一个查询编写查询,以便从 在新闻提要中嵌套的评论,其中包含从该人以及该人的朋友发布的带有有效用户名和用户照片的帖子?

更新

-- phpMyAdmin SQL Dump
-- version 4.8.3
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Oct 09, 2018 at 04:18 PM
-- Server version: 10.1.36-MariaDB
-- PHP Version: 7.2.10

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Database: `gamersapi`
--

-- --------------------------------------------------------

--
-- Table structure for table `feed_item_comment`
--

CREATE TABLE `feed_item_comment` (
  `ID` int(11) NOT NULL,
  `postid` int(11) NOT NULL,
  `userid` int(11) NOT NULL,
  `comment` varchar(3000) NOT NULL,
  `timestamp` int(11) NOT NULL,
  `likes` int(11) NOT NULL,
  `commentid` int(11) NOT NULL,
  `replies` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `feed_item_comment`
--

INSERT INTO `feed_item_comment` (`ID`, `postid`, `userid`, `comment`, `timestamp`, `likes`, `commentid`, `replies`) VALUES
(1, 184, 1, 'comment', 1539080007, 0, 0, 0),
(2, 186, 14, 'VBVBVB', 1539084437, 0, 0, 0),
(3, 186, 14, 'VVV', 1539084448, 0, 0, 0),
(4, 187, 4, 'zzz', 1539084875, 0, 0, 0);

--
-- Indexes for dumped tables
--

--
-- Indexes for table `feed_item_comment`
--
ALTER TABLE `feed_item_comment`
  ADD PRIMARY KEY (`ID`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `feed_item_comment`
--
ALTER TABLE `feed_item_comment`
  MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;


-- phpMyAdmin SQL Dump
-- version 4.8.3
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Oct 09, 2018 at 04:18 PM
-- Server version: 10.1.36-MariaDB
-- PHP Version: 7.2.10

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Database: `gamersapi`
--

-- --------------------------------------------------------

--
-- Table structure for table `feed_item`
--

CREATE TABLE `feed_item` (
  `ID` int(11) NOT NULL,
  `userid` int(11) NOT NULL,
  `content` text NOT NULL,
  `timestamp` time NOT NULL,
  `imageid` int(11) NOT NULL,
  `likes` int(11) NOT NULL,
  `comments` int(11) NOT NULL,
  `user_flag` int(11) NOT NULL,
  `likes_data` varchar(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `feed_item`
--

INSERT INTO `feed_item` (`ID`, `userid`, `content`, `timestamp`, `imageid`, `likes`, `comments`, `user_flag`, `likes_data`) VALUES
(1, 1, 'How are you', '00:00:00', 0, 0, 0, 0, 'like'),
(2, 1, 'How are you doing', '00:00:00', 0, 0, 0, 0, 'like'),
(3, 1, 'This is my test', '00:00:00', 0, 0, 0, 0, 'like'),
(4, 1, 'Hello', '838:59:59', 0, 0, 0, 0, 'like'),
(5, 1, 'hello', '00:00:00', 0, 0, 0, 0, 'like'),
(6, 1, 'Hello hi', '00:00:00', 0, 0, 0, 0, 'like'),
(7, 1, 'gmail', '00:00:00', 0, 0, 0, 0, 'like'),



--
-- Indexes for dumped tables
--

--
-- Indexes for table `feed_item`
--
ALTER TABLE `feed_item`
  ADD PRIMARY KEY (`ID`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `feed_item`
--
ALTER TABLE `feed_item`
  MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=188;
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;



-- phpMyAdmin SQL Dump
-- version 4.8.3
-- https://www.phpmyadmin.net/
--
-- Host: 127.0.0.1
-- Generation Time: Oct 09, 2018 at 04:20 PM
-- Server version: 10.1.36-MariaDB
-- PHP Version: 7.2.10

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Database: `gamersapi`
--

-- --------------------------------------------------------

--
-- Table structure for table `user_friends`
--

CREATE TABLE `user_friends` (
  `ID` int(11) NOT NULL,
  `userid` int(11) NOT NULL,
  `friendid` int(11) NOT NULL,
  `status` int(11) NOT NULL,
  `timestamp` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `user_friends`
--

INSERT INTO `user_friends` (`ID`, `userid`, `friendid`, `status`, `timestamp`) VALUES
(1, 8, 4, 2, 1538369252),
(2, 1, 2, 2, 1538454842),
(3, 7, 1, 2, 1538455395),
(4, 7, 2, 2, 1538455487),
(5, 11, 2, 3, 1538455512),
(6, 6, 2, 2, 1538455567),
(7, 2, 5, 2, 1538456136),
(8, 1, 6, 1, 1538491568),
(9, 12, 1, 2, 1538499199),
(12, 1, 7, 1, 1538565860),
(13, 14, 1, 2, 1538800794);

--
-- Indexes for dumped tables
--

--
-- Indexes for table `user_friends`
--
ALTER TABLE `user_friends`
  ADD PRIMARY KEY (`ID`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `user_friends`
--
ALTER TABLE `user_friends`
  MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=14;

--
-- Constraints for dumped tables
--

--
-- Constraints for table `user_friends`
--
ALTER TABLE `user_friends`
  ADD CONSTRAINT `user_friends_ibfk_1` FOREIGN KEY (`ID`) REFERENCES `users` (`ID`);
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

3 个答案:

答案 0 :(得分:1)

请考虑将ON子句条件AND ft.userid IN (SELECT u.ID ...替换为WHERE子句,因为此表达式是在非 feed_item JOIN上设置的,特别是 users JOIN

SELECT DISTINCT ft.ID as ID, ft.userid, ft.content, ft.timestamp, 
       ft.likes, ft.comments, ftc.comment, u.username, u.avatar 
FROM feed_item_comment ftc
LEFT JOIN feed_item ft 
  ON ftc.postid = ft.ID 
 AND ftc.userid = ft.userid
 AND ftc.userid != '".$this->user->info->ID."'
LEFT JOIN user_friends uf 
  ON uf.friendid = ftc.userid 
LEFT JOIN users u 
  ON u.ID = uf.friendid 
WHERE ft.userid IN               -- ONLY CHANGE
  (SELECT u.ID 
   FROM users u 
    WHERE u.ID IN (SELECT uf.friendid FROM user_friends uf 
                   WHERE uf.status = '2' AND uf.userid = '".$this->user->info->ID."') 
       OR u.ID IN (SELECT uf.userid FROM user_friends uf 
                   WHERE uf.status = '2' AND uf.friendid = '".$this->user->info->ID."')
       OR u.ID = '".$this->user->info->ID."'
  )     
ORDER BY ft.ID DESC

请参见WHERE上的thread与使用ON的{​​{1}}子句条件。

答案 1 :(得分:1)

这就是我所拥有的。但是,因为您对结果的了解不清楚,所以我不想花很多时间尝试解决可能不是您需要的东西。

SQL DEMO

-- get friends of userid = 1

SELECT CASE WHEN userid = 1 THEN friendid
            WHEN friendid = 1 THEN userid
            ELSE id 
       END as id
FROM `user_friends` 
WHERE ID = 1 
   OR ( 1 IN ( `userid`, `friendid`) AND `status` = 2);

-- get all the messages from 1 and his friends

SELECT *
FROM feed_item
WHERE userid IN (
                    SELECT CASE WHEN userid = 1 THEN friendid
                                WHEN friendid = 1 THEN userid
                                ELSE id 
                           END as id
                    FROM `user_friends` 
                    WHERE ID = 1 
                       OR ( 1 IN ( `userid`, `friendid`) AND `status` = 2)
                );

答案 2 :(得分:1)

以下查询用于获取所有新闻提要项

df['Time'] = df['Value']
df['Value'] = df['Value'].mask(mask).ffill()
df = df[mask].copy()
print (df)
    Value  Number   Time
1   Foo X       1  10:00
2   Foo X       2  10:00
3   Foo X       3  10:00
4   Foo X       4  10:00
6   Bar X       1  11:00
7   Bar X       2  11:00
9   Cat X       1  12:00
10  Cat X       2  12:00
11  Cat X       3  12:00

从脚本的服务器端(即PHP)迭代上述执行的SQL中的值时 我们将获得与新闻提要的帖子ID相关的所有评论

SELECT DISTINCT
  ft.ID AS ID,
  ft.userid,
  ft.content,
  ft.timestamp,
  ft.likes,
  ft.comments,
  u.username,
  u.avatar,
  ft.friend_id,
  ft.friend_username
FROM
  feed_item ft
  LEFT JOIN users u
    ON ft.userid = u.ID
WHERE ft.userid = u.ID
  AND ft.userid IN
  (SELECT
    u1.ID
  FROM
    users u1
  WHERE u1.ID IN
    (SELECT
      uf.friendid
    FROM
      user_friends uf
    WHERE uf.status = '2'
      AND uf.userid = '".$this->user->info->ID."')
    OR u1.ID IN
    (SELECT
      uf2.userid
    FROM
      user_friends uf2
    WHERE uf2.status = '2'
      AND uf2.friendid = '".$this->user->info->ID."')
    AND u1.ID != '".$this->user->info->ID."')
ORDER BY ft.ID DESC

这个逻辑对我有用,如果没有必要忽略其余部分,我就包含了更多的列值。进行单个查询会很麻烦