简体   繁体   中英

MySQL: Select all entries grouped by a column with a common value in another column

I have the following table posts:

id | user_id | post_title | is published
1    9332      some title   0
2    2133      some title   1
3    9332      some title   0
4    2133      some title   1
5    4555      some title   0
6    4555      some title   1
7    3221      some title   0
8    3221      some title   0

My goal: Looking for all entries which have the same user_id and of which there is no single entry with "is published" = 1.

So as an result I must get entries with the id 1, 3, 7 and 8 => these are entries of users who do not have any single published post so far.

What would the query be like?

EXTENDED:

A fiddle can be found here:

http://sqlfiddle.com/#!9/b58fb3/1/0

In addition, I created Table 2. My goal is that only Table 1 entries of users will be shown who do not have a linked entry in Table 2. So what I aim for is that after executing the query only Table 1 entries with the IDs 1 and 3 are left (only user 9332 entries).

Try This:

SELECT 
    distinct user_id
FROM 
    table
WHERE user_id not in (SELECT DISTINCT user_id FROM table WHERE is_published = 1)

You can use not exists :

SELECT t.* 
FROM t 
WHERE NOT EXISTS (SELECT 1 
                  FROM t t2 
                  WHERE t2.user_id = t.user_id AND
                        t2.is_published = 1
                 ); 

For your example, all users have at least two entries. This query will return users with one unpublished entry. It is not clear if this is desirable or not. If not, it is pretty simple to modify the query.

Using Nested Query :

SELECT DISTINCT `id`, 
                `user_id`, 
                `post_title`, 
                `is published`
FROM table1
WHERE user_id NOT IN (SELECT DISTINCT user_id FROM table1 WHERE `is published` = 1)
AND user_id  NOT IN (SELECT DISTINCT T1.user_id
                     FROM Table1 T1
                     INNER JOIN Table2 T2
                     ON T1.id=T2.table1_id)

OR Using Joins :

SELECT T1.*
FROM
Table1 T1
INNER JOIN
(
SELECT user_id,COUNT(*) AS CNT
FROM TABLE1 
GROUP BY user_id
) T2
ON T1.user_id=T2.user_id
INNER JOIN
(
SELECT user_id,COUNT(*) AS CNT FROM Table1
WHERE `is published` = 0
GROUP BY user_id
) T3
ON T2.user_id=T3.user_id
AND T2.CNT=T3.CNT
WHERE T1.user_id
NOT IN (
        SELECT T1.user_id
        FROM Table1 T1
        INNER JOIN Table2 T2
        ON T1.id=T2.table1_id
       )

Output

id  user_id post_title  is published
1   9332    some title  0
3   9332    some title  0

Demo

http://sqlfiddle.com/#!9/2d5cb8/12

The simple way is to use SUBQUERY with GROUP BY and HAVING clause. We can return duplicate rows but not having is_published = 1 then join with outer query to return the record of matching ids

SELECT t.id,
    t.user_id,
    t.post_title,
    t.is_published 
FROM temp t
INNER JOIN (SELECT user_id
            FROM temp
            GROUP BY user_id HAVING SUM(is_published) = 0) u ON u.user_id = t.user_id
ORDER BY t.id

OUTPUT:

id  user_id post_title  is_published
1   9332    some title  0
3   9332    some title  0
7   3221    some title  0
8   3221    some title  0

Eg:

Note: Do not use spaces in table/column identifiers. I have amended the column name accordingly.

SELECT x.* 
  FROM table1 x 
  LEFT
  JOIN table1 y
    ON y.user_id = x.user_id
   AND y.is_published = 1
 WHERE x.is_published = 0
   AND y.id IS NULL;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM