source

두 표의 세 번째 표의 카운트 함수를 사용하여 마리아에서 문을 선택합니다.DB

goodcode 2022. 9. 21. 00:00
반응형

두 표의 세 번째 표의 카운트 함수를 사용하여 마리아에서 문을 선택합니다.DB

몇 시간 동안 MariaDB 문서와 다양한 질문을 읽고 원하는 SQL 문을 찾아냈습니다.난 절대 전문가가 아니야결국 기대했던 결과는 나왔는데 왜 효과가 있는지 모르겠어요.실제로 원하는 결과를 얻을 수 있는지 확인하고 싶습니다.또, 지금까지의 몇개의 테스트 케이스에 대해서만 효과가 있는 것은 아닙니다.

게스트북, 사용자 및 user_likes 세 개의 테이블이 있습니다.사용자로부터 사용자 이름과 이름, 투고 내용, 투고 날짜, 게스트북의 투고 ID를 반환하는 SQL 스테이트먼트를 작성하려고 합니다.또한 세 번째 컬럼은 게스트북의 투고 ID가 user_likes 테이블에 표시되는 횟수의 합계입니다.표준 유형의 투고만 반환하고 투고 날짜 오름차순까지 행 순서를 지정해야 합니다.

샘플 데이터:

CREATE TABLE users
    (`user_id` int, `user_first` varchar(6), `user_last` varchar(7),
     `user_email` varchar(26), `user_uname` varchar(6))
;
    
INSERT INTO users
    (`user_id`, `user_first`, `user_last`, `user_email`, `user_uname`)
VALUES
    (0, 'Bob', 'Abc', 'email@example.com', 'user1'),
    (13, 'Larry', 'Abc', 'email@example.com', 'user2'),
    (15, 'Noel', 'Abc', 'email@example.com', 'user3'),
    (16, 'Kate', 'Abc', 'email@example.com', 'user4'),
    (17, 'Walter', 'Sobchak', 'walter.sobchak@shabbus.com', 'Walter'),
    (18, 'Jae', 'Abc', 'email@example.com', 'user5')
;


CREATE TABLE user_likes
    (`user_id` int, `post_id` int, `like_id` int)
;
    
INSERT INTO user_likes
    (`user_id`, `post_id`, `like_id`)
VALUES
    (0, 23, 1),
    (0, 41, 2),
    (13, 23, 7)
;


CREATE TABLE guestbook
    (`post_id` int, `user_id` int, `post_date` datetime,
     `post_content` varchar(27), `post_type` varchar(8),
     `post_level` int, `post_parent` varchar(4))
;
    
INSERT INTO guestbook
    (`post_id`, `user_id`, `post_date`, `post_content`,
     `post_type`, `post_level`, `post_parent`)
VALUES
    (2, 0, '2018-12-15 20:32:40', 'test1', 'testing', 0, NULL),
    (8, 0, '2018-12-16 14:06:40', 'test2', 'testing', 0, NULL),
    (9, 13, '2018-12-16 15:47:55', 'test4', 'testing', 0, NULL),
    (23, 0, '2018-12-25 17:59:46', 'Merry Christmas!', 'standard', 0, NULL),
    (39, 16, '2018-12-26 00:28:04', 'Hello!', 'standard', 0, NULL),
    (40, 15, '2019-01-27 00:46:12', 'Hello 2', 'standard', 0, NULL),
    (41, 18, '2019-02-25 00:44:35', 'What are you doing?', 'standard', 0, NULL)
;

카운트에 관한 복잡한 진술을 많이 해봤지만 원하는 것을 얻을 수 없었다.바보 같은 운으로 보이는 것을 통해 나는 내가 원하는 것을 주는 것처럼 보이는 이 진술을 우연히 작성하게 되었다.

SELECT 
  u.user_uname, u.user_first, g.post_id, g.post_date,
  g.post_content, count(user_likes.post_id) AS likes
FROM
  users AS u, guestbook AS g
LEFT JOIN
  user_likes on g.post_id=user_likes.post_id
WHERE
  u.user_id=g.user_id AND g.post_type='standard'
GROUP BY
  g.post_id
ORDER BY
  g.post_date ASC;

질문:.이 카운트 기능이 작동하는 것처럼 보이는 이유는 무엇입니까?

제가 사용할 수 있었던 카운트 함수는 이것입니다만, 하드 코드화된 post_id 값에만 사용할 수 있습니다.

SELECT COUNT(CASE post_id WHEN 23 THEN 1 ELSE null END) FROM user_likes;

이 값으로 변경하여 게스트북 테이블에서 post_id를 대조하려고 하면 user_likes 테이블 전체로 보이는 잘못된 값이 나타납니다.

SELECT COUNT(case when guestbook.post_id=user_likes.post_id then 1 else null end) FROM guestbook, user_likes;

추가GROUP BY guestbook.post_id마지막까지 더 가까워지겠지만, 이제 어떻게 하면 내가 선택한 문장과 결합할 수 있을지 생각해내야 해.

+----------------------------------------------------------------------------+
| COUNT(case when guestbook.post_id=user_likes.post_id then 1 else null end) |
+----------------------------------------------------------------------------+
|                                                                          0 |
|                                                                          0 |
|                                                                          0 |
|                                                                          2 |
|                                                                          0 |
|                                                                          0 |
|                                                                          1 |
+----------------------------------------------------------------------------+

이게 제가 원하는 결과입니다.나는 단지 내 진술이 믿을 만하거나 옳다는 것을 믿지 않을 뿐이다.

+------------+------------+---------+---------------------+---------------------+-------+
| user_uname | user_first | post_id | post_date           | post_content        | likes |
+------------+------------+---------+---------------------+---------------------+-------+
| user1      | Bob        |      23 | 2018-12-25 17:59:46 | Merry Christmas!    |     2 |
| user4      | Kate       |      39 | 2018-12-26 00:28:04 | Hello!              |     0 |
| user3      | Noel       |      40 | 2019-01-27 00:46:12 | Hello 2             |     0 |
| user5      | Jae        |      41 | 2019-02-25 00:44:35 | What are you doing? |     1 |
+------------+------------+---------+---------------------+---------------------+-------+

설명 조작: http://sqlfiddle.com/ #!9/9/968656/1/0

JOIN+COUNT-- 쿼리는 처음에 에 의해 지시된 대로 테이블을 결합합니다.JOIN그리고.ON절을 참조하십시오.결과는 (적어도 논리적으로) 임시 테이블에 저장됩니다.대부분의 경우 이 임시 테이블에는 다른 테이블보다 더 많은 행이 있습니다.JOINed.

그 다음에COUNT(..)실행됩니다.임시 테이블의 행 수를 카운트하고 있습니다.그 숫자가 정확히 당신이 원하는 숫자일 수도 있고, 엄청나게 부풀려진 숫자일 수도 있습니다.

count(user_likes.post_id)에는, , 즉, 합니다.user_likes.post_id IS NULL 때는 '어울릴 수 없다'라고 하면 이,,, 단게게게말됩 됩됩됩됩됩됩됩COUNT(*).

Commist(Commist) 「」를 사용합니다.FROM a JOIN b ON ...서, 「」는ON은 테이블이 '''를 사용하는지를 .a ★★★★★★★★★★★★★★★★★」b련이있있 있있있다다을 「필터링」, 「필터링」에 .WHERE절을 클릭합니다.

경우,COUNT너무 커요.개발한 쿼리는 접어두고 카운티를 계산하는 딱 한 가지 작업을 하는 쿼리를 개발하려면 다시 시작해야 합니다.이 쿼리는 아마 더 적은 수의 테이블을 사용합니다.

그 위에 구축하여 필요한 다른 데이터를 얻을 수 있습니다.이렇게 생겼을 수도 있어요

SELECT ...
    FROM ( SELECT foo, COUNT(*) AS ct FROM t1 GROUP BY foo ) AS sub1
    JOIN t2 ON t2.foo = sub1.foo
    JOIN t3 ON ...
    WHERE ...

첫 .COUNT그런 다음 필요한 경우 다시 도움을 요청하십시오.

브라이언이 한 것처럼

네, 몇 가지 변경했습니다.

SELECT  u.user_uname, u.user_first,
        g2.post_id, g2.post_content, g2.post_date,
        sub.likes
    FROM  
    (
        SELECT  g.post_id,
                SUM(g.post_id = ul.post_id) AS likes
            FROM  guestbook AS g
            JOIN user_likes AS ul
            WHERE  g.post_type = 'standard'
    ) AS sub
    JOIN  guestbook AS g2  ON sub.post_id = g2.post_id
    JOIN  users AS u       ON u.user_id = g2.user_id;

인덱스:

guestbook:  (post_type, post_id)  -- for derived table
guestbook:  (post_id)             -- for outer SELECT
users:  (user_id)
user_likes:  (post_id)
    

주의:

  • ORDER BY문맥상 무용지물이기 때문에 제거했습니다.
  • COUNT..CASE으로 SUM.
  • JOIN ON

파생된 테이블에서 얻을 수 있는 값은 1개뿐이므로 이 값은 동일하게 동작할 수 있습니다.

SELECT  u.user_uname, u.user_first,
        g.post_id, g.post_content, g.post_date,
        ( SELECT  COUNT(*)
            FROM user_likes AS ul
            WHERE g.post_id = ul.post_id
        ) AS likes
    FROM  guestbook AS g
    JOIN  users AS u   USING(user_id);
    WHERE g.post_type = 'standard'

이것은 많은 변화를 수반했다. 그것이 '올바른' 것처럼 보이는지.그것은 이제 훨씬 더 간단해졌다.

색인은 위와 같습니다.

언급URL : https://stackoverflow.com/questions/63698519/using-the-count-function-on-third-table-in-two-table-select-statement-in-mariadb

반응형